Files
wnmj/Classes/Network/SocketEngine.cpp
2026-02-13 14:34:15 +08:00

318 lines
7.2 KiB
C++

#include <sstream>
#include "SocketEngine.h"
#include "PlatformHeader.h"
using namespace std;
//////////////////////////////////////////////////////////////////////////
CSocketEngine::CSocketEngine()
{
cocos2d::log("CSocketEngine::CSocketEngine()");
mISocketEngineSink = 0;
// 接收缓冲
mTempBuf = new uint8[SIZE_TCP_BUFFER];
ASSERT(mTempBuf != nullptr);
m_dwSendPacketCount = 0;
m_dwRecvPacketCount = 0;
// add by lesten
temp_size_ = 0;
}
CSocketEngine::~CSocketEngine()
{
delete [] mTempBuf;
mTempBuf = nullptr;
mISocketEngineSink=0;
disconnect();
}
//////////////////////////////////////////////////////////////////////////
// ISocketEngine 接口实现
/** 设置Socket接收器 */
void CSocketEngine::setSocketEngineSink(ISocketEngineSink* pISocketEngineSink)
{
mISocketEngineSink = pISocketEngineSink;
}
void CSocketEngine::initValue()
{
m_dwSendPacketCount = 0;
m_dwRecvPacketCount = 0;
temp_size_ = 0;
if (mTempBuf != nullptr)
{
memset(mTempBuf, 0x0, SIZE_TCP_BUFFER);
}
}
/** 链接网络 **/
bool CSocketEngine::connect(const char* url, int port)
{
initValue();
cocos2d::log("Connect url=%s, port=%d ", url, port);
m_oInetAddress.setIp(url);
m_oInetAddress.setPort(port);
return cocos2d::ClientNetDelegate::connect();
}
/** 关闭网络 **/
bool CSocketEngine::disconnect()
{
//恢复数据
initValue();
if (isAlive())
{
cocos2d::ClientNetDelegate::disconnect();
}
return true;
}
/** 发送数据 **/
bool CSocketEngine::send(int main, int sub, void* data, int dataSize)
{
if (!isAlive())
{
return false;
}
//构造数据
unsigned char cbDataBuffer[SOCKET_TCP_BUFFER];
TCP_Head * pHead = (TCP_Head *)cbDataBuffer;
pHead->CommandInfo.wMainCmdID = main;
pHead->CommandInfo.wSubCmdID = sub;
if (dataSize > 0)
{
memcpy(pHead + 1, data, dataSize);
}
//加密数据
unsigned short wSendSize = EncryptBuffer(cbDataBuffer, sizeof(TCP_Head)+dataSize, sizeof(cbDataBuffer));
cocos2d::ClientNetDelegate::send((const char*)cbDataBuffer, wSendSize);
return true;
}
/** 状态判断 **/
bool CSocketEngine::isAlive()
{
return cocos2d::ClientNetDelegate::isConnected();
}
//////////////////////////////////////////////////////////////////////////
// 接口ClientNetDelegate
void CSocketEngine::onConnected()
{
if (mISocketEngineSink != 0)
{
mISocketEngineSink->onEventTCPSocketLink();
}
}
void CSocketEngine::onDisconnected()
{
if (mISocketEngineSink != nullptr)
{
mISocketEngineSink->onEventTCPSocketShut();
}
}
void CSocketEngine::onConnectTimeout()
{
if (mISocketEngineSink != nullptr)
{
mISocketEngineSink->onEventTCPSocketError(0);
}
}
void CSocketEngine::onExceptionCaught(CCSocketStatus eStatus)
{
if (mISocketEngineSink != 0)
{
mISocketEngineSink->onEventTCPSocketError(eStatus);
}
}
void CSocketEngine::onMessageReceived(char* pData, unsigned int iLenght)
{
static uint8 cbBufRecieve[SIZE_TCP_BUFFER];
int nRecvSize = 0;
// add by lesten
if (temp_size_!=0){
nRecvSize += temp_size_;
memcpy( &cbBufRecieve[0], mTempBuf, temp_size_ );
temp_size_ = 0;
memset(mTempBuf, SIZE_TCP_BUFFER, 0);
}
if (nRecvSize + iLenght >= SIZE_TCP_BUFFER)
{
cocos2d::log("nRecvSize + dataSize >= SIZE_TCP_BUFFER");
disconnect();
return;
}
memcpy(&cbBufRecieve[nRecvSize], pData, iLenght);
nRecvSize += iLenght;
//变量定义
unsigned short wPacketSize = 0;
uint8 cbDataBuffer[SOCKET_TCP_PACKET + sizeof(TCP_Head)];
TCP_Head * pHead = (TCP_Head *)cbBufRecieve;
while (nRecvSize >= sizeof(TCP_Head))
{
wPacketSize = pHead->TCPInfo.wPacketSize;
if (pHead->TCPInfo.cbDataKind != DK_MAPPED)
{
disconnect();
return;
}
if (wPacketSize > (SOCKET_TCP_PACKET + sizeof(TCP_Head)))
{
disconnect();
return;
}
if (nRecvSize < wPacketSize){
temp_size_ = nRecvSize;
memcpy(mTempBuf, cbBufRecieve, temp_size_);
return;
}
//拷贝数据
m_dwRecvPacketCount++;
memcpy(cbDataBuffer, cbBufRecieve, wPacketSize);
nRecvSize -= wPacketSize;
memmove(cbBufRecieve, cbBufRecieve + wPacketSize, nRecvSize);
//解密数据
unsigned short wRealySize = CrevasseBuffer(cbDataBuffer, wPacketSize);
if (wRealySize < sizeof(TCP_Head))
{
return;
}
//解释数据
unsigned short wDataSize = wRealySize - sizeof(TCP_Head);
void * pDataBuffer = cbDataBuffer + sizeof(TCP_Head);
TCP_Command Command = ((TCP_Head *)cbDataBuffer)->CommandInfo;
if (Command.wMainCmdID == MDM_KN_COMMAND && Command.wSubCmdID == SUB_KN_DETECT_SOCKET)
{
cocos2d::log("REV- --main command---- %d -- Sub Command ----%d---\n", Command.wMainCmdID, Command.wSubCmdID);
send(MDM_KN_COMMAND, SUB_KN_DETECT_SOCKET, pDataBuffer, wDataSize);
if (mISocketEngineSink)
{
mISocketEngineSink->onEventTCPHeartTick();
}
continue;
}
else
{
cocos2d::log("REV- --main command---- %d -- Sub Command ----%d---\n", Command.wMainCmdID, Command.wSubCmdID);
}
if (mISocketEngineSink != 0)
{
bool bHandle = mISocketEngineSink->onEventTCPSocketRead(Command.wMainCmdID, Command.wSubCmdID, pDataBuffer, wPacketSize - 8);
if (!bHandle)
{
cocos2d::log("Error REV- --main command---- %d -- Sub Command ----%d---\n", Command.wMainCmdID, Command.wSubCmdID);
CCASSERT(false,"");
disconnect();
return;
}
}
}
}
//加密数据
unsigned short CSocketEngine::EncryptBuffer(unsigned char * pcbDataBuffer, unsigned short wDataSize, unsigned short wBufferSize)
{
//调整长度
unsigned short wEncryptSize = wDataSize - sizeof(TCP_Command), wSnapCount = 0;
if ((wEncryptSize%sizeof(unsigned int)) != 0)
{
wSnapCount = sizeof(unsigned int)-wEncryptSize%sizeof(unsigned int);
memset(pcbDataBuffer + sizeof(TCP_Info)+wEncryptSize, 0, wSnapCount);
}
//效验码与字节映射
unsigned char cbCheckCode = 0;
unsigned short i = 0;
for (i = sizeof(TCP_Info); i < wDataSize; i++)
{
cbCheckCode += pcbDataBuffer[i];
pcbDataBuffer[i] = MapSendByte(pcbDataBuffer[i]);
}
//填写信息头
TCP_Head * pHead = (TCP_Head *)pcbDataBuffer;
pHead->TCPInfo.cbCheckCode = ~cbCheckCode + 1;
pHead->TCPInfo.wPacketSize = wDataSize;
pHead->TCPInfo.cbDataKind = DK_MAPPED;
//设置变量
m_dwSendPacketCount++;
return wDataSize;
}
//解密数据
unsigned short CSocketEngine::CrevasseBuffer(unsigned char pcbDataBuffer[], unsigned short wDataSize)
{
//ASSERT(m_dwSendPacketCount > 0);
ASSERT(wDataSize >= sizeof(TCP_Head));
ASSERT(((TCP_Head *)pcbDataBuffer)->TCPInfo.wPacketSize == wDataSize);
//调整长度
unsigned short wSnapCount = 0;
if ((wDataSize%sizeof(unsigned int)) != 0)
{
wSnapCount = sizeof(unsigned int)-wDataSize%sizeof(unsigned int);
memset(pcbDataBuffer + wDataSize, 0, wSnapCount);
}
//效验码与字节映射
TCP_Head * pHead = (TCP_Head *)pcbDataBuffer;
unsigned char cbCheckCode = pHead->TCPInfo.cbCheckCode;
for (int i = sizeof(TCP_Info); i < wDataSize; i++)
{
pcbDataBuffer[i] = MapRecvByte(pcbDataBuffer[i]);
cbCheckCode += pcbDataBuffer[i];
}
if (cbCheckCode != 0)
{
return 0;
}
return wDataSize;
}
//映射发送数据
unsigned char CSocketEngine::MapSendByte(unsigned char const cbData)
{
unsigned char cbMap = g_SendByteMap[cbData];
return cbMap;
}
//映射接收数据
unsigned char CSocketEngine::MapRecvByte(unsigned char const cbData)
{
unsigned char cbMap = g_RecvByteMap[cbData];
return cbMap;
}