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