All pastes #45051 Raw Edit

Something

public cpp v1 · immutable
#45051 ·published 2006-03-09 19:02 UTC
rendered paste body
// IOCPSocket2.cpp: implementation of the CIOCPSocket2 class.////////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "IOCPSocket.h"#include "CircularBuffer.h"#include "Compress.h"#include "Packetdefine.h"#include "define.h"#include "Logger.h"#include "User.h"#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endifvoid bb() {};		// nop function//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////CIOCPSocket2::CIOCPSocket2(){	m_pBuffer = new CCircularBuffer(SOCKET_BUFF_SIZE);	m_pRegionBuffer = new _REGION_BUFFER;	m_pCompressMng = new CCompressMng;	m_Socket = INVALID_SOCKET;	m_pIOCPort = NULL;	m_Type = TYPE_ACCEPT;	// Cryption	m_CryptionFlag = 0;}CIOCPSocket2::~CIOCPSocket2(){	delete m_pBuffer;	delete m_pRegionBuffer;	delete m_pCompressMng;}BOOL CIOCPSocket2::Create( UINT nSocketPort, int nSocketType, long lEvent, LPCTSTR lpszSocketAddress){	int ret;	struct linger lingerOpt;	m_Socket = socket( AF_INET, nSocketType/*SOCK_STREAM*/, 0 );	if( m_Socket == INVALID_SOCKET ) {		ret = WSAGetLastError();		TRACE("Socket Create Fail! - %d\n", ret);		return FALSE;	}	m_hSockEvent = WSACreateEvent();	if( m_hSockEvent == WSA_INVALID_EVENT ) {		ret = WSAGetLastError();		TRACE("Event Create Fail! - %d\n", ret);		return FALSE;	}	// Linger off -> close socket immediately regardless of existance of data 	//	lingerOpt.l_onoff = 0;	lingerOpt.l_linger = 0;	setsockopt(m_Socket, SOL_SOCKET, SO_LINGER, (char *)&lingerOpt, sizeof(lingerOpt));	int socklen;	socklen = SOCKET_BUFF_SIZE*4;	setsockopt( m_Socket, SOL_SOCKET, SO_RCVBUF, (char*)&socklen, sizeof(socklen));		socklen = SOCKET_BUFF_SIZE*4;	setsockopt( m_Socket, SOL_SOCKET, SO_SNDBUF, (char*)&socklen, sizeof(socklen));		return TRUE;}BOOL CIOCPSocket2::Connect( CIOCPort* pIocp, LPCTSTR lpszHostAddress, UINT nHostPort ){	struct sockaddr_in addr;	memset((void *)&addr, 0, sizeof(addr));	addr.sin_family = AF_INET;	addr.sin_addr.s_addr = inet_addr(lpszHostAddress);	addr.sin_port = htons(nHostPort);	int result = connect( m_Socket,(struct sockaddr *)&addr,sizeof(addr) );	if ( result == SOCKET_ERROR )	{		int err = WSAGetLastError();//		TRACE("CONNECT FAIL : %d\n", err);		closesocket( m_Socket );		return FALSE;	}	ASSERT( pIocp );	InitSocket( pIocp );	m_Sid = m_pIOCPort->GetClientSid();	if( m_Sid < 0 )		return FALSE;	m_pIOCPort->m_ClientSockArray[m_Sid] = this;		if ( !m_pIOCPort->Associate(this, m_pIOCPort->m_hClientIOCPort) )	{		TRACE("Socket Connecting Fail - Associate\n");		return FALSE;	}	m_ConnectAddress = lpszHostAddress;	m_State = STATE_CONNECTED;	m_Type = TYPE_CONNECT;	Receive();	return TRUE;}int CIOCPSocket2::Send(char *pBuf, long length, int dwFlag){	int ret_value = 0;	WSABUF out;	DWORD sent = 0;	OVERLAPPED *pOvl;	HANDLE	hComport = NULL;	if( length > MAX_PACKET_SIZE )		return 0;	BYTE pTBuf[MAX_PACKET_SIZE];	BYTE pTIBuf[MAX_PACKET_SIZE];	BYTE pTOutBuf[MAX_PACKET_SIZE];	memset( pTBuf, 0x00, MAX_PACKET_SIZE );	memset( pTIBuf, 0x00, MAX_PACKET_SIZE );	memset( pTOutBuf, 0x00, MAX_PACKET_SIZE );	int index = length;	if(dwFlag == 0) // crypt	{		crypt.Encrypt(pBuf+2,((CUser*)this)->_key,length-2);		unsigned char k[256];		for(int i=0;i<8;i++)		{			k[i] = ((CUser*)this)->_key[i];		}	}	memcpy( pTBuf, pBuf, length );		dwFlag=0;	out.buf = (char*)pTBuf;	out.len = length;		pOvl = &m_SendOverlapped;	pOvl->Offset = OVL_SEND;	pOvl->OffsetHigh = out.len;	ret_value = WSASend( m_Socket, &out, 1, &sent, dwFlag, pOvl, NULL);	CLogger::ShowMessage("#[%s][%d] requested to send: %d",__FILE__,__LINE__,length);		if ( ret_value == SOCKET_ERROR )	{		int last_err;		last_err = WSAGetLastError();		if ( last_err == WSA_IO_PENDING ) {			TRACE("SEND : IO_PENDING[SID=%d]", m_Sid);			m_nPending++;			if( m_nPending > 3 )				goto close_routine;			sent = length; 		}		else if ( last_err == WSAEWOULDBLOCK )		{			TRACE("SEND : WOULDBLOCK[SID=%d]", m_Sid);			m_nWouldblock++;			if( m_nWouldblock > 3 )				goto close_routine;			return 0;		}		else		{			TRACE("SEND : ERROR [SID=%d] - %d\n", m_Sid, last_err);			m_nSocketErr++;			goto close_routine;		}	}	else if ( !ret_value )	{		m_nPending = 0;		m_nWouldblock = 0;		m_nSocketErr = 0;	}	return sent;close_routine:	pOvl = &m_RecvOverlapped;	pOvl->Offset = OVL_CLOSE;		if( m_Type == TYPE_ACCEPT )		hComport = m_pIOCPort->m_hServerIOCPort;	else		hComport = m_pIOCPort->m_hClientIOCPort;		PostQueuedCompletionStatus( hComport, (DWORD)0, (DWORD)m_Sid, pOvl );		return -1;}int CIOCPSocket2::Receive(){	int RetValue;	WSABUF in;	DWORD insize, dwFlag=0;	OVERLAPPED *pOvl;	HANDLE	hComport = NULL;	memset(m_pRecvBuff, NULL, MAX_PACKET_SIZE );	in.len = MAX_PACKET_SIZE;	in.buf = m_pRecvBuff;	pOvl = &m_RecvOverlapped;	pOvl->Offset = OVL_RECEIVE;	RetValue = WSARecv( m_Socket, &in, 1, &insize, &dwFlag, pOvl, NULL ); 	if ( RetValue == SOCKET_ERROR )	{		int last_err;		last_err = WSAGetLastError();		if ( last_err == WSA_IO_PENDING ) {//			TRACE("RECV : IO_PENDING[SID=%d]", m_Sid);//			m_nPending++;//			if( m_nPending > 3 )//				goto close_routine;			return 0;		}		else if ( last_err == WSAEWOULDBLOCK )		{			TRACE("RECV : WOULDBLOCK[SID=%d]", m_Sid);			m_nWouldblock++;			if( m_nWouldblock > 3 )				goto close_routine;			return 0;		}		else		{			TRACE("RECV : ERROR [SID=%d] - %d\n", m_Sid, last_err);			m_nSocketErr++;			if( m_nSocketErr == 2 )				goto close_routine;			return -1;		}	}	return (int)insize;close_routine:	pOvl = &m_RecvOverlapped;	pOvl->Offset = OVL_CLOSE;		if( m_Type == TYPE_ACCEPT )		hComport = m_pIOCPort->m_hServerIOCPort;	else		hComport = m_pIOCPort->m_hClientIOCPort;		PostQueuedCompletionStatus( hComport, (DWORD)0, (DWORD)m_Sid, pOvl );		return -1;}void CIOCPSocket2::ReceivedData(int length){	if(!length) return;	int len = 0;	m_pBuffer->PutData(m_pRecvBuff, length);		char *pData = new char[length];	//char *pDecData = new char[length-2];	m_pBuffer->GetData((char*)pData, length);	m_pBuffer->HeadIncrease(length);		if(pData)	{		Parsing(length, pData);		delete[] pData;		pData = NULL;	}}BOOL CIOCPSocket2::PullOutCore(char *&data, int &length){	BYTE		*pTmp;	BYTE		*pBuff;	int			len;	BOOL		foundCore;	MYSHORT		slen;	DWORD		wSerial = 0;	int index = 1, recv_packet = 0;	len = m_pBuffer->GetValidCount();	if(len == 0 || len < 0) return FALSE;	pTmp = new BYTE[len];	m_pBuffer->GetData((char*)pTmp, len);	foundCore = FALSE;	int	sPos=0, ePos = 0;	for (int i = 0; i < len && !foundCore; i++)	{		if (i+2 >= len) break;		if (pTmp[i] == PACKET_START1 && pTmp[i+1] == PACKET_START2)		{//			if( m_wPacketSerial >= wSerial ) goto cancelRoutine;			sPos = i+2;			slen.b[0] = pTmp[sPos];			slen.b[1] = pTmp[sPos + 1];			length = slen.w;			if( length < 0 ) goto cancelRoutine;			if( length > len ) goto cancelRoutine;			ePos = sPos+length + 2;			if( (ePos + 2) > len ) goto cancelRoutine;//			ASSERT(ePos+2 <= len);			if (pTmp[ePos] == PACKET_END1 && pTmp[ePos+1] == PACKET_END2)			{				if( m_CryptionFlag )	{					pBuff = new BYTE[length+1]; 					if(pBuff[0] != 0xfc)	{						TRACE("CIOCPSocket2::PutOutCore - Decryption Error... sockid(%d)\n", m_Socket);						delete[] pBuff;						Close();						goto cancelRoutine;					}					recv_packet = (WORD)GetShort( (char*)pBuff, index );					//TRACE("^^^ IOCPSocket2,, PullOutCore ,,, recv_val = %d ^^^\n", recv_packet);					if( m_Rec_val >= recv_packet )	{						if( recv_packet == 0 )	{							m_Rec_val = recv_packet;						}						else	{							TRACE("CIOCPSocket2::PutOutCore - recv_packet Error... sockid(%d), len=%d, recv_packet=%d \n", m_Socket, length, recv_packet);							delete[] pBuff;							m_pBuffer->HeadIncrease(6+length); //6: header 2+ end 2+ length 2 + cryption 4							goto cancelRoutine;						}					}					else	m_Rec_val = recv_packet;					length = length-4;					if( length <= 0 )	{						TRACE("CIOCPSocket2::PutOutCore - length Error... sockid(%d), len=%d\n", m_Socket, length);						delete[] pBuff;						Close();						goto cancelRoutine;					}					data = new char[length+1];					CopyMemory((void *)data, (const void *)(pBuff+4), length);					data[length] = 0;					foundCore = TRUE;					int head = m_pBuffer->GetHeadPos(), tail = m_pBuffer->GetTailPos();					delete[] pBuff;				}				else	{					// 					data = new char[length+1];					CopyMemory((void *)data, (const void *)(pTmp+sPos+2), length);					data[length] = 0;					foundCore = TRUE;					int head = m_pBuffer->GetHeadPos(), tail = m_pBuffer->GetTailPos();					//TRACE("data : %s, len : %d\n", data, length);				}//				TRACE("data : %s, len : %d\n", data, length);//				TRACE("head : %d, tail : %d\n", head, tail );				break;			}			else 			{				m_pBuffer->HeadIncrease(3);				break;			}		}	}	if( m_CryptionFlag )	{		if (foundCore) m_pBuffer->HeadIncrease(10+length); //6: header 2+ end 2+ length 2 + cryption 4	}	else	{		if (foundCore) m_pBuffer->HeadIncrease(6+length); //6: header 2+ end 2+ length 2	}	delete[] pTmp;	return foundCore;cancelRoutine:		delete[] pTmp;	return foundCore;}BOOL CIOCPSocket2::AsyncSelect( long lEvent ){	int retEventResult, err;	retEventResult = WSAEventSelect( m_Socket, m_hSockEvent, lEvent );	err = WSAGetLastError();	return ( !retEventResult );}BOOL CIOCPSocket2::SetSockOpt( int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel ){	int retValue;	retValue = setsockopt( m_Socket, nLevel, nOptionName, (char *)lpOptionValue, nOptionLen );	return ( !retValue );}BOOL CIOCPSocket2::ShutDown( int nHow ){	int retValue;	retValue = shutdown( m_Socket, nHow );	return ( !retValue );}void CIOCPSocket2::Close(){	if ( m_pIOCPort == NULL ) return;	HANDLE	hComport = NULL;	OVERLAPPED		*pOvl;	pOvl = &m_RecvOverlapped;	pOvl->Offset = OVL_CLOSE;	if( m_Type == TYPE_ACCEPT )		hComport = m_pIOCPort->m_hServerIOCPort;	else		hComport = m_pIOCPort->m_hClientIOCPort;	int retValue = PostQueuedCompletionStatus( hComport, (DWORD)0, (DWORD)m_Sid, pOvl );	if ( !retValue ) {		int errValue;		errValue = GetLastError();		TRACE("PostQueuedCompletionStatus Error : %d\n", errValue);	}}void CIOCPSocket2::CloseProcess(){	m_State = STATE_DISCONNECTED;	if( m_Socket != INVALID_SOCKET )		closesocket( m_Socket );}void CIOCPSocket2::InitSocket( CIOCPort* pIOCPort ){	m_pIOCPort = pIOCPort;	m_RecvOverlapped.hEvent = NULL;	m_SendOverlapped.hEvent = NULL;	m_pBuffer->SetEmpty();	m_nSocketErr = 0;	m_nPending = 0;	m_nWouldblock = 0;	Initialize();}BOOL CIOCPSocket2::Accept( SOCKET listensocket, struct sockaddr* addr, int* len ){	m_Socket = accept( listensocket, addr, len);	if( m_Socket == INVALID_SOCKET) {		int err = WSAGetLastError();		TRACE("Socket Accepting Fail - %d\n", err);		return FALSE;	}	return TRUE;}void CIOCPSocket2::Parsing(int length, char *pData){}void CIOCPSocket2::Initialize(){	m_wPacketSerial = 0;	m_pRegionBuffer->iLength = 0;	memset( m_pRegionBuffer->pDataBuff, 0x00, REGION_BUFF_SIZE );	m_CryptionFlag = 0;}void CIOCPSocket2::SendCompressingPacket(const char *pData, int len){	if( len <= 0 || len >= 49152)	{		TRACE("### SendCompressingPacket Error : len = %d ### \n", len);		return;	}	int send_index = 0, count = 0;	char send_buff[49152];		memset(send_buff, 0x00, 49152);	do {		if( m_pCompressMng->m_nBufferStatus == W ) {			bb();			count++;			continue;		}		m_pCompressMng->m_nBufferStatus = W;		m_pCompressMng->m_dwThreadID =  ::GetCurrentThreadId();		bb();		if( m_pCompressMng->m_dwThreadID != ::GetCurrentThreadId() ) {	// Dual Lock System...			count++;			continue;		}		m_pCompressMng->PreCompressWork(pData, len);		m_pCompressMng->Compress();		SetByte(send_buff, WIZ_COMPRESS_PACKET, send_index );		SetShort(send_buff, (short)m_pCompressMng->m_nOutputBufferCurPos, send_index );		SetShort(send_buff, (short)m_pCompressMng->m_nOrgDataLength, send_index );		SetDWORD(send_buff, m_pCompressMng->m_dwCrc, send_index);		SetString( send_buff, m_pCompressMng->m_pOutputBuffer, m_pCompressMng->m_nOutputBufferCurPos, send_index);		m_pCompressMng->Initialize();	// buffer clear		m_pCompressMng->m_nBufferStatus = E;		break;	} while( count < 50 );	if( count > 49 ) {		TRACE("Compressing Fail Packet\n");		Send( (char*)pData, len );	}	else		Send( send_buff, send_index );}void CIOCPSocket2::RegionPacketAdd(char *pBuf, int len){	int count = 0;	do {		if( m_pRegionBuffer->bFlag == W ) {			bb();			count++;			continue;		}		m_pRegionBuffer->bFlag = W;		m_pRegionBuffer->dwThreadID = ::GetCurrentThreadId();		bb();		if( m_pRegionBuffer->dwThreadID != ::GetCurrentThreadId() ) {	// Dual Lock System...			count++;			continue;		}		SetShort( m_pRegionBuffer->pDataBuff, len, m_pRegionBuffer->iLength );		SetString( m_pRegionBuffer->pDataBuff, pBuf, len, m_pRegionBuffer->iLength );		m_pRegionBuffer->bFlag = WR;		break;	} while( count < 30 );	if( count > 29 ) {//		TRACE("Region packet Add Drop\n");		Send( pBuf, len );	}}void CIOCPSocket2::RegioinPacketClear(char* GetBuf, int& len){	int count = 0;	do {		if( m_pRegionBuffer->bFlag == W ) {			bb();			count++;			continue;		}		m_pRegionBuffer->bFlag = W;		m_pRegionBuffer->dwThreadID = ::GetCurrentThreadId();		bb();		if( m_pRegionBuffer->dwThreadID != ::GetCurrentThreadId() ) {	// Dual Lock System...			count++;			continue;		}				int index = 0;		SetByte( GetBuf, WIZ_CONTINOUS_PACKET, index );		SetShort( GetBuf, m_pRegionBuffer->iLength, index );		SetString( GetBuf, m_pRegionBuffer->pDataBuff, m_pRegionBuffer->iLength, index );		len = index;		memset( m_pRegionBuffer->pDataBuff, 0x00, REGION_BUFF_SIZE );		m_pRegionBuffer->iLength = 0;		m_pRegionBuffer->bFlag = E;		break;	} while( count < 30 );	if( count > 29 )		TRACE("Region packet Clear Drop\n");}