#include #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; }