18,362
社区成员




#ifndef _CIRCUITQUEUE_H_
#define _CIRCUITQUEUE_H_
#include <windows.h>
#include <stdio.h>
#include <assert.h>
template<typename T>
class CircuitQueue
{
public:
CircuitQueue() : m_pData( NULL ), m_nLength( 0 ), m_nSize( 0 ), m_nHead( 0 ), m_nTail( 0 )
{
InitializeCriticalSection( &m_cs );
}
virtual ~CircuitQueue()
{
if( m_pData ) delete [] m_pData;
DeleteCriticalSection( &m_cs );
}
void Create( int nSize, int nExtraSize = 0 )
{
EnterCriticalSection( &m_cs );
if( m_pData ) delete [] m_pData;
m_pData = new T[nSize + nExtraSize];
m_nSize = nSize;
m_nExtraSize = nExtraSize;
LeaveCriticalSection( &m_cs );
}
inline void Clear()
{
EnterCriticalSection( &m_cs );
m_nLength = 0;
m_nHead = 0;
m_nTail = 0;
LeaveCriticalSection( &m_cs );
}
inline int GetSpace()
{
int iRet;
EnterCriticalSection( &m_cs );
iRet = m_nSize - m_nLength;
LeaveCriticalSection( &m_cs );
return iRet;
}
inline int GetLength()
{
int iRet;
EnterCriticalSection( &m_cs );
iRet = m_nLength;
LeaveCriticalSection( &m_cs );
return iRet;
}
inline int GetBackDataCount()
{
int iRet;
EnterCriticalSection( &m_cs );
iRet = m_nSize - m_nHead;
LeaveCriticalSection( &m_cs );
return iRet;
}
inline T* GetReadPtr()
{
T *pRet;
EnterCriticalSection( &m_cs );
pRet = m_pData + m_nHead;
int nSplitFirstDataCount;
if( m_nHead > m_nTail && ( nSplitFirstDataCount = m_nSize - m_nHead ) < m_nExtraSize )
{
memcpy( m_pData + m_nSize, m_pData, sizeof(T) * ( m_nExtraSize - nSplitFirstDataCount ) );
}
LeaveCriticalSection( &m_cs );
return pRet;
}
inline T* GetWritePtr()//获取可以写的地址
{
T *pRet;
EnterCriticalSection( &m_cs );
pRet = m_pData + m_nTail;
LeaveCriticalSection( &m_cs );
return pRet;
}
inline int GetReadableLen()
{
int iRet;
EnterCriticalSection( &m_cs );
if( m_nHead == m_nTail ) iRet = GetLength() > 0 ? m_nSize - m_nHead: 0;
else if( m_nHead < m_nTail ) iRet = m_nTail - m_nHead;
else iRet = m_nSize - m_nHead;
LeaveCriticalSection( &m_cs );
return iRet;
}
inline int GetWritableLen()
{
int iRet;
EnterCriticalSection( &m_cs );
if( m_nHead == m_nTail ) iRet = GetLength() > 0 ? 0 : m_nSize - m_nTail;
else if( m_nHead < m_nTail ) iRet = m_nSize - m_nTail;
else iRet = m_nHead - m_nTail;
LeaveCriticalSection( &m_cs );
return iRet;
}
//入队
inline BOOL Enqueue( T *pSrc, int nSize )
{
EnterCriticalSection( &m_cs );
if( GetSpace() < nSize )
{
LeaveCriticalSection( &m_cs );
return FALSE;
}
/*
BOOL bCopyToExtraBuffer = ( ( m_nHead <= m_nTail ) && ( m_nSize - m_nTail < nSize ) );
*/
if( pSrc )
{
if( m_nHead <= m_nTail )
{
int nBackSpaceCount = m_nSize - m_nTail;
if( nBackSpaceCount >= nSize )
{
memcpy( m_pData + m_nTail, pSrc, sizeof(T) * nSize );
}
else
{
memcpy( m_pData + m_nTail, pSrc, sizeof(T) * nBackSpaceCount );
memcpy( m_pData, pSrc + nBackSpaceCount, sizeof(T) * ( nSize - nBackSpaceCount ) );
}
}
else
{
memcpy( m_pData + m_nTail, pSrc, sizeof(T) * nSize );
}
}
/*
if( bCopyToExtraBuffer )
{
memcpy( m_pData + m_nSize, pSrc + m_nSize - m_nTail, sizeof(T) * ( nSize - ( m_nSize - m_nTail ) ) );
}
*/
m_nTail += nSize;
m_nTail %= m_nSize;
m_nLength += nSize;
LeaveCriticalSection( &m_cs );
return TRUE;
}
//出队
inline BOOL Dequeue( T *pTar, int nSize )
{
EnterCriticalSection( &m_cs );
if( !Peek( pTar, nSize ) )
{
LeaveCriticalSection( &m_cs );
return FALSE;
}
m_nHead += nSize;
m_nHead %= m_nSize;
m_nLength -= nSize;
LeaveCriticalSection( &m_cs );
return TRUE;
}
//获取数据
inline BOOL Peek( T *pTar, int nSize )
{
EnterCriticalSection( &m_cs );
if( m_nLength < nSize )
{
LeaveCriticalSection( &m_cs );
return FALSE;
}
if( pTar != NULL )
{
if( m_nHead < m_nTail )
{
memcpy( pTar, m_pData + m_nHead, sizeof(T) * nSize );
}
else
{
if( GetBackDataCount() >= nSize )
{
memcpy( pTar, m_pData + m_nHead, sizeof(T) * nSize );
}
else
{
memcpy( pTar, m_pData + m_nHead, sizeof(T) * GetBackDataCount() );
memcpy( pTar + GetBackDataCount(), m_pData, sizeof(T) * ( nSize - GetBackDataCount() ) );
}
}
}
LeaveCriticalSection( &m_cs );
return TRUE;
}
inline void CopyHeadDataToExtraBuffer( int nSize )
{
assert( nSize <= m_nExtraSize );
EnterCriticalSection( &m_cs );
//缓冲阻截后加一个额外的缓冲区写入数据。
memcpy( m_pData + m_nSize, m_pData, nSize );
LeaveCriticalSection( &m_cs );
}
protected:
CRITICAL_SECTION m_cs;
T *m_pData; ///队列缓冲区指针
int m_nLength; ///数据长度
int m_nSize; ///缓冲队列大小
int m_nHead; ///投
int m_nTail; ///尾
int m_nExtraSize; ///额外队列缓冲区大小
};
#endif
#ifndef _RECVBUFFER_H_
#define _RECVBUFFER_H_
#include <windows.h>
#include "CircuitQueue.h"
#include "NetBase.h"
class RecvBuffer
{
public:
RecvBuffer() { m_pQueue = NULL; }
virtual ~RecvBuffer() { if( m_pQueue ) delete m_pQueue; }
inline VOID Create( int nBufferSize, DWORD dwExtraBufferSize ) {
if( m_pQueue ) delete m_pQueue;
m_pQueue = new CircuitQueue<BYTE>;
m_pQueue->Create( nBufferSize, dwExtraBufferSize ); }
inline VOID Completion( int nBytesRecvd ) { m_pQueue->Enqueue( NULL, nBytesRecvd ); }
inline VOID Clear() { m_pQueue->Clear(); }
inline VOID GetRecvParam( BYTE **ppRecvPtr, int &nLength ) {
*ppRecvPtr = m_pQueue->GetWritePtr();
nLength = m_pQueue->GetWritableLen(); }
inline BYTE* GetFirstPacketPtr() {
PACKET_HEADER header;
if( !m_pQueue->Peek( (BYTE*)&header, sizeof(PACKET_HEADER) ) ) return NULL;
if( m_pQueue->GetLength() <3 /*(int)( sizeof(PACKET_HEADER) + header.size+2 )*/ ) return NULL;
if( m_pQueue->GetBackDataCount() < (int)( header.size +2 + sizeof(header) ) ) {
m_pQueue->CopyHeadDataToExtraBuffer( header.size + 2 + sizeof(header) - m_pQueue->GetBackDataCount() ); }
return m_pQueue->GetReadPtr(); }
inline VOID RemoveFirstPacket( WORD wSize ) {
if (m_pQueue->Dequeue( NULL, wSize )==FALSE)
{
m_pQueue->Clear();
}
}
private:
CircuitQueue<BYTE> *m_pQueue;
};
#endif
BOOL Session::PreRecv()
{
WSABUF wsabuf;
m_pRecvBuffer->GetRecvParam( (BYTE**)&wsabuf.buf, (int&)wsabuf.len );//获取可写的首地址和可写大小
ZeroMemory( &m_recvIoData, sizeof(OVERLAPPEDEX) );
m_recvIoData.dwOperationType = RECV_POSTED;
int ret = WSARecv( GetSocket(), &wsabuf, 1, &m_recvIoData.dwIoSize, &m_recvIoData.dwFlags, &m_recvIoData, NULL );
if( ret == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING )
{
return FALSE;
}
return TRUE;
}
case RECV_POSTED:
pSession->GetRecvBuffer()->Completion( dwIoSize );
//下一个Recv
if( !pSession->PreRecv() )
{
Beep(100,200);
}
break;
typedef struct _header
{
DWORD dwType; //包类型
DWORD dwLen; //数据长度
}HDR, *PHDER;