www.pudn.com > ChatUseIOCP.rar > ChatProtocol.cpp


#include "StdAfx.h" 
#include ".\ChatProtocol.h" 
 
ChatProtocol::ChatProtocol(void) 
{ 
	m_pInPacket = NULL; 
} 
 
ChatProtocol::~ChatProtocol() 
{ 
} 
 
//Ovverride the standard version 
bool ChatProtocol::Send(Packet& OutPacket) 
{ 
	//Create a new temp buffer 
	char *pszBuffer = new char[OutPacket.dwDataSize + CHAT_HEADER_SIZE + 1]; 
	if (!pszBuffer) 
		throw "ChatProtocol::Send, Cant create a buffer"; 
 
	//Add data to the buffer 
	pszBuffer[0] = STX; 
	memcpy(pszBuffer + 1, &OutPacket.nFunctionCode, USHORTSIZE); 
	memcpy(pszBuffer + 3, &OutPacket.dwDataSize, DWORDSIZE); 
	memcpy(pszBuffer + 7, &OutPacket.Status, CHARSIZE); 
	memcpy(pszBuffer + CHAT_HEADER_SIZE, OutPacket.pData, OutPacket.dwDataSize); 
	pszBuffer[OutPacket.dwDataSize + CHAT_HEADER_SIZE] = ETX; 
 
	//Send data 
#ifdef __SERVER_SIDE__ 
	bool bRet = DtServerSocketClient::Send(pszBuffer, OutPacket.dwDataSize + CHAT_HEADER_SIZE + 1); 
#else 
	bool bRet = DtIpSocket::Send(pszBuffer, OutPacket.dwDataSize + CHAT_HEADER_SIZE + 1); 
#endif 
 
	return bRet; 
} 
 
 
//Return the number of bytes that we have read from the buffer, 
#ifdef __SERVER_SIDE__ 
void ChatProtocol::OnReceive(const char* pInBuffer, size_t nBufSize) 
#else 
void ChatProtocol::HandleReceive(const char* pInBuffer, size_t nBufSize) 
#endif 
{ 
	DWORD dwBytesHandled = 0;		// Number of bytes that we have handled. 
	DWORD dwCopyLen = 0;			// Number of bytes that we have copied from the buffer. 
	bool  bCompleteBuffer = false;	// True if we got a complete buffer. 
 
 
	// Check if we already have started building a packet. 
	if (!m_pInPacket) 
	{ 
		DWORD dwSkipCount = 0;		//number of bytes we had to skip to find stx 
 
		//We must get atleast 6 bytes. (stx, func <2 bytes>, size <2 bytes>, status) 
		if (nBufSize < CHAT_HEADER_SIZE)  
			return; 
 
		//Check if we got a STX 
		//======================================================== 
		if (pInBuffer[0] != STX) 
		{ 
 
			//loop through the array and try to find STX 
			bool bFound = false; 
			for (dwSkipCount = 1; dwSkipCount < nBufSize - 1; dwSkipCount++) 
			{ 
				if (pInBuffer[dwSkipCount] == STX) 
				{ 
					bFound = true; 
					break; 
				} 
			} 
 
			// didnt find a valid trans (or atleast STX) 
			if (!bFound) return; 
 
			char szLog[128]; 
			sprintf(szLog, "Skipping %d bytes in recieve buffer", dwSkipCount); 
#ifdef __SERVER_SIDE__ 
			WriteLog(Datatal::LP_HIGH, GetClientId(), "Send", szLog); 
#else 
			WriteLog(Datatal::LP_HIGH, "Read", "Skipped X bytes from the recieve buffer."); 
#endif 
		} 
 
		m_pInPacket = new Packet; 
 
		//Check if we got a complete packet 
		DWORD dwSize = 0; 
		memcpy(&m_pInPacket->nFunctionCode, pInBuffer + dwSkipCount + CHARSIZE, USHORTSIZE); //skip stx 
		memcpy(&dwSize,						pInBuffer + dwSkipCount + CHARSIZE+USHORTSIZE, DWORDSIZE); //skip stx, funccode 
		memcpy(&m_pInPacket->Status,		pInBuffer + dwSkipCount + CHARSIZE+USHORTSIZE+DWORDSIZE, CHARSIZE);	//skip stx, funccode, size 
 
		if (dwSize) 
		{ 
			m_pInPacket->dwBufferSize = dwSize + 1; 
			m_pInPacket->pData = new char[m_pInPacket->dwBufferSize]; 
			if (!m_pInPacket->pData) 
			{ 
				Disconnect(); 
				char szLog[128]; 
				sprintf(szLog, "Skipping %d bytes in recieve buffer", dwSkipCount); 
#ifdef __SERVER_SIDE__ 
				WriteLog(Datatal::LP_HIGH, GetClientId(), "Read", "OnReceive, Failed to create packet buffer."); 
#else 
				WriteLog(Datatal::LP_HIGH, "Read", "OnReceive, Failed to create packet buffer."); 
#endif 
				return; 
			} 
 
			// Copy everything that we got in the buffer. 
			dwCopyLen = (int)(nBufSize - dwSkipCount - CHAT_HEADER_SIZE); 
			if (dwCopyLen > dwSize) 
			{ 
				dwCopyLen = dwSize; 
				bCompleteBuffer = true; 
			} 
 
			memcpy(m_pInPacket->pData, pInBuffer + CHAT_HEADER_SIZE + dwSkipCount, dwCopyLen); 
 
			m_pInPacket->dwDataSize = dwCopyLen; 
			m_pInPacket->pData[dwCopyLen] = 0; 
 
			dwBytesHandled = dwCopyLen + CHAT_HEADER_SIZE + dwSkipCount; 
		} // We got a buffer. 
		else 
		{ 
			// no buffer, handle recieve. 
			dwBytesHandled = CHAT_HEADER_SIZE + dwSkipCount; 
			bCompleteBuffer = true; 
		} 
 
	} //if (!pInPacket) 
 
	else  //We do got a buffer, but not a complete one. 
	{ 
 
		// Check if we got a complete transaction with this one. 
		if (nBufSize + m_pInPacket->dwDataSize >= m_pInPacket->dwBufferSize - 1) 
		{ 
			dwCopyLen = m_pInPacket->dwBufferSize - m_pInPacket->dwDataSize - 1; 
			bCompleteBuffer = true; 
		} 
		else 
			dwCopyLen = (DWORD)nBufSize; 
 
		memcpy(m_pInPacket->pData + m_pInPacket->dwDataSize, pInBuffer, dwCopyLen); 
		m_pInPacket->dwDataSize += dwCopyLen; 
		m_pInPacket->pData[m_pInPacket->dwDataSize] = 0; 
 
		dwBytesHandled = dwCopyLen; 
	} 
 
 
	// Got a complete transaction 
	if (bCompleteBuffer)  
	{ 
		if ( pInBuffer[dwBytesHandled] != ETX) 
		{ 
#ifdef __SERVER_SIDE__ 
			WriteLog(Datatal::LP_HIGH, GetClientId(), "Read", "Incorrect TRANS, no ETX! FuncCode: %d, Size: %d, nStatus: %d", m_pInPacket->nFunctionCode, m_pInPacket->dwDataSize, m_pInPacket->Status); 
#else 
			WriteLog(Datatal::LP_HIGH, "Read", "Incorrect TRANS, no ETX! FuncCode: %d, Size: %d, nStatus: %d", m_pInPacket->nFunctionCode, m_pInPacket->dwDataSize, m_pInPacket->Status); 
#endif 
			if (m_pInPacket->dwDataSize < 900) 
			{ 
#ifdef __SERVER_SIDE__ 
				WriteLog(Datatal::LP_HIGH, GetClientId(), "Incorrect TRANS Data: %s", m_pInPacket->pData); 
#else 
				WriteLog(Datatal::LP_HIGH, "Read", "Incorrect TRANS Data: %s", m_pInPacket->pData); 
#endif 
			} 
 
			Disconnect(); 
			return; 
		} 
 
		dwBytesHandled++; //Increase one for the etx. 
		HandlePacket(m_pInPacket); 
		m_pInPacket = NULL; 
 
#ifdef __SERVER_SIDE__ 
		if (nBufSize - (size_t)dwBytesHandled) OnReceive(pInBuffer + dwBytesHandled, nBufSize - (size_t)dwBytesHandled); 
#else 
		if (nBufSize - (size_t)dwBytesHandled) HandleReceive(pInBuffer + dwBytesHandled, nBufSize - (size_t)dwBytesHandled); 
#endif 
	} 
 
 
} 
 
void ChatProtocol::SetPacketBuffer(Packet& ThePacket, const char* szData, DWORD dwSize) 
{ 
	ThePacket.dwBufferSize = (DWORD)dwSize+1; 
	ThePacket.dwDataSize = (DWORD)dwSize; 
	if (ThePacket.pData) delete[] ThePacket.pData; 
 
	ThePacket.pData = new char[ThePacket.dwBufferSize]; 
	if (!ThePacket.pData) 
		throw "ChatProtocol::SetPacketBuffer, Failed to create packet buffer."; 
 
	ThePacket.pData[ThePacket.dwDataSize] = 0; 
	memcpy(ThePacket.pData, szData, ThePacket.dwDataSize); 
} 
 
 
#ifdef __AFX_H__ 
void ChatProtocol::SetPacketBuffer(Packet& ThePacket, CString& strData) 
{ 
	ThePacket.dwDataSize = (DWORD)strData.GetLength(); 
	ThePacket.dwBufferSize = ThePacket.dwDataSize+1; 
	if (ThePacket.pData) delete[] ThePacket.pData; 
 
	ThePacket.pData = new char[ThePacket.dwBufferSize]; 
	if (!ThePacket.pData) 
		throw "ChatProtocol::SetPacketBuffer, Failed to create packet buffer."; 
 
	ThePacket.pData[ThePacket.dwDataSize] = 0; 
	memcpy(ThePacket.pData, strData, ThePacket.dwDataSize); 
} 
#endif 
 
#ifdef _STRING_ 
void ChatProtocol::SetPacketBuffer(Packet& ThePacket, std::string& strData) 
{ 
	ThePacket.dwDataSize = (DWORD)strData.size(); 
	ThePacket.dwBufferSize = ThePacket.dwDataSize+1; 
	if (ThePacket.pData) delete[] ThePacket.pData; 
 
	ThePacket.pData = new char[ThePacket.dwBufferSize]; 
	if (!ThePacket.pData) 
		throw "ChatProtocol::SetPacketBuffer, Failed to create packet buffer."; 
 
	ThePacket.pData[ThePacket.dwDataSize] = 0; 
	memcpy(ThePacket.pData, strData.c_str(), ThePacket.dwDataSize); 
} 
#endif