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

466 lines
14 KiB
C#
Raw Normal View History

2024-08-23 15:49:34 +08:00
/********************************************************************************
* SocketInputStream.cs
* \NetWork\SocketAPI\SocketInputStream.cs
*
* 2013-11-29
*
* Socket的应用层输入缓冲区
*
*
*********************************************************************************/
using System;
using System.Collections.Generic;
using System.Net;
using Module.Log;
#if UNITY_WP8
using UnityPortSocket;
#else
using System.Net.Sockets;
#endif
namespace SPacket.SocketInstance
{
public class SocketInputStream
{
public const uint SOCKET_ERROR = 0xFFFFFFFF;
public const uint DEFAULT_SOCKET_INPUT_BUFFER_SIZE = 1024 * 256;
public const uint MAX_SOCKET_INPUT_BUFFER_SIZE = 1024 * 1024 * 8;
public SocketInputStream (SocketInstance socket,
uint BufferLen = DEFAULT_SOCKET_INPUT_BUFFER_SIZE,
uint MaxBufferLen = MAX_SOCKET_INPUT_BUFFER_SIZE)
{
m_pSocket = socket;
m_BufferLen = BufferLen;
m_MaxBufferLen = MaxBufferLen;
m_Head = 0;
m_Tail = 0;
m_Buffer = new Byte[BufferLen];
m_BufferTemp = new Byte[BufferLen];
}
void ClearBufferTemp()
{
if (m_BufferTemp != null)
{
int nCount = m_BufferTemp.Length;
Array.Clear(m_BufferTemp, 0, nCount);
}
}
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 uint Read(Byte[] buf, uint len )
{
if ( len == 0 )
return 0 ;
if ( len > Length() )
return 0 ;
if ( m_Head < m_Tail )
{
for(uint i =0;i< len;++i)
{
buf[i] = m_Buffer[m_Head+i];
}
}
else
{
uint rightLen = m_BufferLen-m_Head ;
if( len<=rightLen )
{
for (uint i = 0; i < len; ++i)
{
buf[i] = m_Buffer[m_Head + i];
}
}
else
{
for (uint i = 0; i < rightLen; ++i)
{
buf[i] = m_Buffer[m_Head + i];
}
for (uint i = 0; i < len - rightLen; ++i)
{
buf[i + rightLen] = m_Buffer[i];
}
}
}
m_Head = (m_Head+len)%m_BufferLen ;
return len ;
}
public bool Peek( Byte[] buf,uint len )
{
if( len==0 )
return false ;
if( len>Length() )
return false ;
if( m_Head<m_Tail )
{
for (uint i = 0; i < len; ++i)
{
buf[i] = m_Buffer[m_Head + i];
}
}
else
{
uint rightLen = m_BufferLen-m_Head ;
if( len<=rightLen )
{
for (uint i = 0; i < len; ++i)
{
buf[i] = m_Buffer[m_Head + i];
}
}
else
{
for (uint i = 0; i < rightLen; ++i)
{
buf[i] = m_Buffer[m_Head + i];
}
for (uint i = 0; i < len - rightLen; ++i)
{
buf[rightLen+i] = m_Buffer[ i];
}
}
}
return true ;
}
public bool Skip (uint len)
{
if (len == 0)
return false;
if (len > Length())
return false;
m_Head = (m_Head + len) % m_BufferLen;
return true;
}
public uint Fill( )
{
uint nFilled = 0;
uint nReceived = 0;
uint nFree = 0;
if(m_pSocket==null) return 0;
if ( m_Head <= m_Tail )
{
if ( m_Head == 0 )
{
//
// H T LEN=10
// 0123456789
// abcd......
//
nReceived = 0 ;
nFree = m_BufferLen-m_Tail-1 ;
if( nFree != 0 )
{
ClearBufferTemp();
nReceived = m_pSocket.receive(m_BufferTemp, (int)nFree);
if (nReceived == SOCKET_ERROR) return SOCKET_ERROR;
for (int i = 0; i < nReceived; ++i)
{
m_Buffer[m_Tail + i] = m_BufferTemp[i];
}
// if (nReceived==SOCKET_ERROR_WOULDBLOCK) return 0 ;
// if (nReceived==SOCKET_ERROR) return SOCKET_ERROR-1 ;
m_Tail += nReceived;
nFilled += nReceived;
}
if( nReceived == nFree )
{
uint available = m_pSocket.available();
if ( available > 0 )
{
if( (m_BufferLen+available+1)>m_MaxBufferLen )
{
var value = m_BufferLen + available + 1;
Initsize( ) ;
return SOCKET_ERROR ;
}
if( !Resize( available+1 ) )
return 0 ;
ClearBufferTemp();
nReceived = m_pSocket.receive(m_BufferTemp, (int)available);
if (nReceived == SOCKET_ERROR) return SOCKET_ERROR;
for (int i = 0; i < nReceived; ++i)
{
m_Buffer[m_Tail + i] = m_BufferTemp[i];
}
// if (nReceived==SOCKET_ERROR_WOULDBLOCK) return 0 ;
// if (nReceived==SOCKET_ERROR) return SOCKET_ERROR-4 ;
//if (nReceived==0) return SOCKET_ERROR-5;
m_Tail += nReceived;
nFilled += nReceived;
}
}
}
else
{
//
// H T LEN=10
// 0123456789
// ...abcd...
//
nFree = m_BufferLen-m_Tail ;
ClearBufferTemp();
nReceived = m_pSocket.receive(m_BufferTemp, (int)nFree);
if (nReceived == SOCKET_ERROR) return SOCKET_ERROR;
for (int i = 0; i < nReceived; ++i)
{
m_Buffer[m_Tail + i] = m_BufferTemp[i];
}
//nReceived = m_pSocket->receive( &m_Buffer[m_Tail], nFree );
// if( nReceived==SOCKET_ERROR_WOULDBLOCK ) return 0 ;
// if( nReceived==SOCKET_ERROR ) return SOCKET_ERROR-6 ;
// if( nReceived==0 ) return SOCKET_ERROR-7 ;
m_Tail = (m_Tail+nReceived)%m_BufferLen ;
nFilled += nReceived ;
if( nReceived==nFree )
{
// Assert( m_Tail == 0 );
nReceived = 0 ;
nFree = m_Head-1 ;
if( nFree!=0 )
{
ClearBufferTemp();
nReceived = m_pSocket.receive(m_BufferTemp, (int)nFree);
if (nReceived == SOCKET_ERROR) return SOCKET_ERROR;
for (int i = 0; i < nReceived; ++i)
{
m_Buffer[i] = m_BufferTemp[i];
}
// nReceived = m_pSocket->receive( &m_Buffer[0] , nFree );
// if( nReceived==SOCKET_ERROR_WOULDBLOCK ) return 0 ;
// if( nReceived==SOCKET_ERROR ) return SOCKET_ERROR -8;
// if( nReceived==0 ) return SOCKET_ERROR-9 ;
m_Tail += nReceived;
nFilled += nReceived;
}
if( nReceived==nFree )
{
uint available = m_pSocket.available();
if ( available > 0 )
{
if( (m_BufferLen+available+1)>m_MaxBufferLen )
{
Initsize( ) ;
return SOCKET_ERROR ;
}
if( !Resize( available+1 ) )
return 0 ;
ClearBufferTemp();
nReceived = m_pSocket.receive(m_BufferTemp, (int)available);
if (nReceived == SOCKET_ERROR) return SOCKET_ERROR;
for (int i = 0; i < nReceived; ++i)
{
m_Buffer[m_Tail + i] = m_BufferTemp[i];
}
// nReceived = m_pSocket->receive( &m_Buffer[m_Tail] , available );
//if (nReceived==SOCKET_ERROR_WOULDBLOCK) return 0 ;
//if (nReceived==SOCKET_ERROR) return SOCKET_ERROR-11 ;
// if (nReceived==0) return SOCKET_ERROR-12;
m_Tail += nReceived;
nFilled += nReceived;
}
}
}
}
}
else
{
//
// T H LEN=10
// 0123456789
// abcd...efg
//
nReceived = 0 ;
nFree = m_Head-m_Tail-1 ;
if( nFree!=0 )
{
ClearBufferTemp();
nReceived = m_pSocket.receive(m_BufferTemp, (int)nFree);
if (nReceived == SOCKET_ERROR) return SOCKET_ERROR;
for (int i = 0; i < nReceived; ++i)
{
m_Buffer[m_Tail + i] = m_BufferTemp[i];
}
// nReceived = m_pSocket->receive( &m_Buffer[m_Tail], nFree ) ;
// if( nReceived==SOCKET_ERROR_WOULDBLOCK ) return 0 ;
//if( nReceived==SOCKET_ERROR ) return SOCKET_ERROR-13 ;
//if( nReceived==0 ) return SOCKET_ERROR-14 ;
m_Tail += nReceived ;
nFilled += nReceived ;
}
if( nReceived==nFree )
{
uint available = m_pSocket.available( ) ;
if ( available>0 )
{
if( (m_BufferLen+available+1)>m_MaxBufferLen )
{
Initsize( ) ;
return SOCKET_ERROR;
}
if( !Resize( available+1 ) )
return 0 ;
ClearBufferTemp();
nReceived = m_pSocket.receive(m_BufferTemp, (int)available);
if (nReceived == SOCKET_ERROR) return SOCKET_ERROR;
for (int i = 0; i < nReceived; ++i)
{
m_Buffer[m_Tail + i] = m_BufferTemp[i];
}
// nReceived = m_pSocket->receive( &m_Buffer[m_Tail], available ) ;
// if( nReceived==SOCKET_ERROR_WOULDBLOCK ) return 0 ;
// if( nReceived==SOCKET_ERROR ) return SOCKET_ERROR-16 ;
// if( nReceived==0 ) return SOCKET_ERROR-17 ;
m_Tail += nReceived ;
nFilled += nReceived ;
}
}
}
return nFilled ;
}
public void Initsize (uint BufferSize = DEFAULT_SOCKET_INPUT_BUFFER_SIZE)
{
m_Head = 0;
m_Tail = 0;
if (BufferSize > m_MaxBufferLen)
{
BufferSize = m_MaxBufferLen;
}
m_Buffer = new Byte[BufferSize];
m_BufferLen = BufferSize;
}
public bool Resize( uint size )
{
LogModule.DebugLog("Resize packet");
size = Math.Max(size, (uint)(m_BufferLen >> 1));
uint newBufferLen = (uint)(m_BufferLen + size);
uint len = Length();
if (m_BufferTemp.Length < newBufferLen)
{
m_BufferTemp = new Byte[newBufferLen];
ClearBufferTemp();
}
if (size < 0)
{
if (newBufferLen < 0 || newBufferLen < len)
return false;
}
Byte[] newBuffer = new Byte[newBufferLen];
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];
}
}
// delete[] m_Buffer;
m_Buffer = newBuffer;
m_BufferLen = newBufferLen;
m_Head = 0;
m_Tail = len;
return true;
}
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;
}
}