Files
JJBB/Assets/Project/Script/GameLogic/NetWork/SocketAPI/SocketInputStream.cs
2024-08-23 15:49:34 +08:00

466 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/********************************************************************************
* 文件名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;
}
}