318 lines
7.2 KiB
C++
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;
|
||
|
|
}
|