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