Files
JJBB/Assets/Project/Script/GameLogic/NetWork/SocketAPI/SocketOutputStream.cs

313 lines
8.2 KiB
C#
Raw Normal View History

2024-08-23 15:49:34 +08:00
/********************************************************************************
* SocketOutputStream.cs
* \NetWork\SocketAPI\SocketOutputStream.cs
*
* 2013-11-29
*
* Socket的应用层输出缓冲区
*
*
*********************************************************************************/
using System;
using System.Collections.Generic;
using System.Net;
#if UNITY_WP8
using UnityPortSocket;
#else
using System.Net.Sockets;
#endif
using System.Text;
#pragma warning disable
namespace SPacket.SocketInstance
{
public class SocketOutputStream
{
public const bool FALSE = false;
public const bool TRUE = true;
public const uint SOCKET_ERROR = 0xFFFFFFFF;
public const uint DEFAULT_SOCKET_OUTPUT_BUFFER_SIZE = 1024 * 8;
public const uint DISCONNECT_SOCKET_OUTPUT_BUFFER_SIZE = 1024 * 20;
public SocketOutputStream( SocketInstance sock,
uint BufferLen = DEFAULT_SOCKET_OUTPUT_BUFFER_SIZE,
uint MaxBufferLen = DISCONNECT_SOCKET_OUTPUT_BUFFER_SIZE)
{
m_pSocket = sock;
m_BufferLen = BufferLen;
m_MaxBufferLen = MaxBufferLen;
m_Head = 0;
m_Tail = 0;
m_Buffer = new Byte[m_BufferLen];
m_BufferTemp = new Byte[m_BufferLen];
}
void ClearBufferTemp()
{
if (m_BufferTemp != null)
{
int nCount = m_BufferTemp.Length;
Array.Clear(m_BufferTemp, 0, nCount);
}
}
public uint Write (Byte[] buf, uint len)
{
uint nFree = ((m_Head <= m_Tail) ? (m_BufferLen - m_Tail + m_Head - 1) : (m_Head - m_Tail - 1));
if (len >= nFree)
{
if (!Resize(len - nFree + 1))
return 0;
}
if (m_Head <= m_Tail)
{
if (m_Head == 0)
{
nFree = m_BufferLen - m_Tail - 1;
// memcpy(&m_Buffer[m_Tail], buf, len);
for (int i = 0; i < len;++i )
{
m_Buffer[m_Tail + i] = buf[i];
}
}
else
{
nFree = m_BufferLen - m_Tail;
if (len <= nFree)
{
//memcpy(&m_Buffer[m_Tail], buf, len);
for (int i = 0; i < len; ++i)
{
m_Buffer[m_Tail + i] = buf[i];
}
}
else
{
//memcpy(&m_Buffer[m_Tail], buf, nFree);
for (int i = 0; i < nFree; ++i)
{
m_Buffer[m_Tail + i] = buf[i];
}
for (int i = 0; i < len - nFree; ++i)
{
m_Buffer[i] = buf[nFree+i];
}
// memcpy(m_Buffer, &buf[nFree], len - nFree);
}
}
}
else
{
// memcpy(&m_Buffer[m_Tail], buf, len);
for (int i = 0; i < len; ++i)
{
m_Buffer[m_Tail + i] = buf[i];
}
}
m_Tail = (m_Tail + len) % m_BufferLen;
return len;
}
public uint Flush ()
{
if (m_pSocket == null) return 0;
uint nFlushed = 0;
uint nSent = 0;
uint nLeft;
SocketFlags flag = SocketFlags.None;
if (m_BufferLen > m_MaxBufferLen)
{
Initsize();
return SOCKET_ERROR;
}
try
{
if ( m_Head < m_Tail )
{
nLeft = m_Tail - m_Head;
while ( nLeft > 0 )
{
ClearBufferTemp();
for (int i=0;i<nLeft;++i)
{
m_BufferTemp[i] = m_Buffer[m_Head+i];
}
nSent = m_pSocket.Send(m_BufferTemp, (int)nLeft, flag);
//LogModule.DebugLog(nSent.ToString());
//if (nSent==SOCKET_ERROR_WOULDBLOCK) return 0 ;
if (nSent==SOCKET_ERROR) return SOCKET_ERROR ;
if (nSent==0) return 0;
nFlushed += nSent;
nLeft -= nSent;
m_Head += nSent;
}
}
else if( m_Head > m_Tail )
{
nLeft = m_BufferLen - m_Head;
while ( nLeft > 0 )
{
ClearBufferTemp();
for (int i=0;i<nLeft;++i)
{
m_BufferTemp[i] = m_Buffer[m_Head+i];
}
nSent = m_pSocket.Send(m_BufferTemp , (int)nLeft , flag );
//if (nSent==SOCKET_ERROR_WOULDBLOCK) return 0 ;
if (nSent==SOCKET_ERROR) return SOCKET_ERROR-3 ;
if (nSent==0) return 0;
nFlushed += nSent;
nLeft -= nSent;
m_Head += nSent;
}
// Assert( m_Head == m_BufferLen );
m_Head = 0;
nLeft = m_Tail;
while ( nLeft > 0 )
{
ClearBufferTemp();
for (int i=0;i<nLeft;++i)
{
m_BufferTemp[i] = m_Buffer[m_Head + i];
}
nSent = m_pSocket.Send(m_BufferTemp, (int)nLeft, flag);
//if (nSent==SOCKET_ERROR_WOULDBLOCK) return 0 ;
if (nSent==SOCKET_ERROR) return SOCKET_ERROR ;
if (nSent==0) return 0;
nFlushed += nSent;
nLeft -= nSent;
m_Head += nSent;
}
}
}
catch
{
if( nSent>0 )
{
m_Head += nSent;
}
}
m_Head = m_Tail = 0 ;
return nFlushed;
}
public void Initsize (uint BufferLen = DEFAULT_SOCKET_OUTPUT_BUFFER_SIZE)
{
m_Head = 0;
m_Tail = 0;
if (BufferLen > m_MaxBufferLen)
{
BufferLen = m_MaxBufferLen;
}
m_Buffer = new Byte[BufferLen];
m_BufferLen = BufferLen;
}
public bool Resize( uint size )
{
uint orgSize = size;
size = Math.Max(size, (uint)(m_BufferLen >> 1));
uint newBufferLen = m_BufferLen + size;
uint len = Length();
if (size < 0)
{
if (newBufferLen < 0 || newBufferLen < len)
return false;
}
Byte[] newBuffer = new Byte[newBufferLen];
if (newBuffer == null)
return false;
if (m_Head < m_Tail)
{
// memcpy(newBuffer, &m_Buffer[m_Head], m_Tail - m_Head);
for (int i = 0; i < m_Tail - m_Head;++i )
{
newBuffer[i] = m_Buffer[m_Head + i];
}
}
else if (m_Head > m_Tail)
{
//memcpy(newBuffer, &m_Buffer[m_Head], m_BufferLen - m_Head);
for (int i = 0; i < m_BufferLen - m_Head; ++i)
{
newBuffer[i] = m_Buffer[m_Head + i];
}
//memcpy(&newBuffer[m_BufferLen - m_Head], m_Buffer, m_Tail);
for (int i = 0; i < m_Tail; ++i)
{
newBuffer[m_BufferLen - m_Head + i] = m_Buffer[i];
}
}
m_Buffer = newBuffer;
m_BufferLen = newBufferLen;
m_Head = 0;
m_Tail = len;
return true;
}
public uint Length ()
{
if (m_Head < m_Tail)
return m_Tail - m_Head;
else if (m_Head > m_Tail)
return m_BufferLen - m_Head + m_Tail;
return 0;
}
public void CleanUp ()
{
m_Head = 0;
m_Tail = 0;
}
SocketInstance m_pSocket;
Byte[] m_Buffer = null;
Byte[] m_BufferTemp = null; //临时缓存解决new的GC问题
uint m_BufferLen;
uint m_MaxBufferLen;
uint m_Head;
uint m_Tail;
}
}