头文件
#ifndef _MTNotification_H_
#define _MTNotification_H_
#include <thread>
#include "SocketSinkHead.h"
#if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)
#include <WinSock2.h>
#include <WS2tcpip.h>
#pragma comment (lib,"WS2_32.Lib")
#define LHS_EAGAIN WSAEWOULDBLOCK
#define LHS_EWOULDBLOCK WSAEWOULDBLOCK
#define LHS_ETIMEDOUT WSAETIMEDOUT
#define LHS_ENETDOWN WSAENETDOWN
#define LHS_WSAEINVAL WSAEINVAL
#else
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include<netinet/tcp.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <arpa/inet.h>
typedef int SOCKET;
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR (-1)
#define LHS_EAGAIN EAGAIN //此操作会令线程阻塞,但socket为不可阻塞的
#define LHS_EWOULDBLOCK EWOULDBLOCK //资源暂时不可用
#define LHS_ETIMEDOUT ETIMEDOUT
#define LHS_ENETDOWN ENETDOWN
#define LHS_WSAEINVAL 10022
#endif
USING_NS_CC;
// TCP 网络连接
class CSocketEngine : public ITCPSocket
{
friend class MTSocketQueue;
// 辅助变量
private:
WORD m_wSocketID; // 网络标识
int m_SocketIndex; // 网络索引
BYTE m_cbSocketStatus; // 网络状态
// 计数变量
private:
DWORD m_dwSendTickCount; // 发送时间
DWORD m_dwRecvTickCount; // 接收时间
// 接收变量
private:
WORD m_wRecvSize; // 接收长度
BYTE m_cbRecvBuf[SOCKET_TCP_BUFFER * 10]; // 接收缓冲
// 内核变量
private:
SOCKET m_hSocket; // 连接句柄
ITCPSocketSink* m_pITCPSocketSink; // 回调接口
std::mutex m_MutexRecv;
// 函数定义
public:
// 构造函数
CSocketEngine();
// 析构函数
virtual ~CSocketEngine();
// 标识接口
public:
// 获取标识
virtual WORD GetSocketID() { return m_wSocketID; }
// 设置标识
virtual void SetSocketID(WORD wSocketID) { m_wSocketID = wSocketID; }
// 配置接口
public:
// 设置接口
virtual bool SetTCPSocketSink(ITCPSocketSink* pIUnknownEx);
// 信息接口
public:
// 获取状态
virtual BYTE GetSocketStatus() { return m_cbSocketStatus; }
// 操作接口
public:
// 连接操作
virtual BYTE Connect(std::string szServerIP, WORD wPort);
// 发送函数
virtual WORD SendData(WORD wMainCmdID, WORD wSubCmdID);
// 发送函数
virtual WORD SendData(WORD wMainCmdID, WORD wSubCmdID, VOID* pData, WORD wDataSize);
// 关闭连接
virtual VOID CloseSocket();
// 辅助函数
protected:
// 连接事件
void OnSocketLink(int nErrorCode);
// 发送数据
WORD SendDataBuffer(void* pBuffer, WORD wSendSize);
// 应答事件
void OnSocketRead(void* pBuffer, WORD wSendSize);
// 关闭连接
void CloseSocket(BYTE cbShutReason);
// 解密数据
WORD CrevasseBuffer(BYTE cbDataBuffer[], WORD wDataSize);
// 加密数据
WORD EncryptBuffer(BYTE cbDataBuffer[], WORD wDataSize, WORD wBufferSize);
private:
static void PerformConnectThread(std::string szServerIP, WORD wPort, int nSocketIndex);
static void PerformRecvectThread(int nSocketIndex);
};
//////////////////////////////////////////////////////////////////////////
#endif // _MTNotification_H_
源文件
#include <iostream>
#include <map>
#include "cocos2d.h"
#include <mutex>
#include "SocketEngine.h"
USING_NS_CC;
//////////////////////////////////////////////////////////////////////////
// 多线程共享消息队列
//////////////////////////////////////////////////////////////////////////
void socket_close(int s)
{
#if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)
shutdown(s, SD_BOTH);
closesocket(s);
#else
shutdown(s, 2);
close(s);
#endif
}
int socket_send(int s, const char* data, int size)
{
unsigned int flags = 0;
#if (CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID)
flags = MSG_NOSIGNAL;
#endif
return send(s, data, size, flags);
}
int socket_recv(int s, char* data, int size)
{
unsigned int flags = 0;
#if (CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID)
flags = MSG_NOSIGNAL;
#endif
return recv(s, data, size, flags);
}
int socket_error()
{
#if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)
return WSAGetLastError();
#else
return errno;
#endif
}
void socket_sleep(unsigned int delay)
{
#if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)
Sleep(delay);
#else
usleep(delay * 1000);
#endif
}
long socket_TickCount()
{
timeval now;
gettimeofday(&now, 0);
return (LONG)(now.tv_sec * 1000 + now.tv_usec / 1000);
}
//////////////////////////////////////////////////////////////////////////
static bool __isSetSig = true;
static int __SocketIndex = 0;
static const BYTE __SocketCount = 100;
static CSocketEngine* __SocketMap[__SocketCount];
static const BYTE EVENT_TCP_SOCKET_LINK = 0; //连接事件
static const BYTE EVENT_TCP_SOCKET_READ = 1; //读取事件
static const BYTE EVENT_TCP_SOCKET_SHUT = 2; //关闭事件
#define GetMTSocketQueue MTSocketQueue::GetInstance()
//////////////////////////////////////////////////////////////////////////
class CInitSock
{
public:
CInitSock()
{
ZeroMemory(__SocketMap, sizeof(__SocketMap));
#if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)
if (__isSetSig)
{
__isSetSig = false;
WSADATA wsaData;
//初始化Socket环境
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
//初始化DLL错误,显示错误提示,程序退出
CCLOG("WSAStartup failed!\nInitialize socket failed.\n");
}
}
#endif
#if (CC_TARGET_PLATFORM==CC_PLATFORM_IOS)
if (__isSetSig)
{
__isSetSig = false;
struct sigaction Sa;
Sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &Sa, 0);
}
#endif
}
~CInitSock()
{
#if (CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)
WSACleanup();
#endif
}
};
CInitSock __InitSock;
//////////////////////////////////////////////////////////////////////////
// 循环消息处理
class MTSocketQueue : public Ref
{
struct MTData
{
BYTE onwer; //数据拥有者
int cmd; //命令:0关闭连接 1:错误码(dataSize) 2:消息
BYTE* data;
int dataSize;
};
std::list<MTData> m_DataQueues;
std::mutex m_Mutex;
static MTSocketQueue* m_sInstance;
private:
MTSocketQueue()
{
Director::getInstance()->getScheduler()->schedule(CC_SCHEDULE_SELECTOR(MTSocketQueue::post), this, 0.0f, false);
}
~MTSocketQueue()
{
std::lock_guard<std::mutex> lk(m_Mutex); //线程开始加锁,退出时自动解锁
while (!m_DataQueues.empty())
{
MTData& mtData = m_DataQueues.front();
if (mtData.data) delete[]mtData.data;
m_DataQueues.pop_front();
}
}
public:
static MTSocketQueue* GetInstance()
{
if (m_sInstance == 0)
m_sInstance = new MTSocketQueue();
return m_sInstance;
}
public:
void PostAsynEventData(BYTE cbIndex, WORD cmd, void* data, WORD dataSize)
{
std::lock_guard<std::mutex> lk(m_Mutex); //线程开始加锁,退出时自动解锁
if (cbIndex > __SocketCount && __SocketMap[cbIndex] == 0) { return; }
MTData mtData;
memset(&mtData, 0, sizeof(mtData));
mtData.onwer = cbIndex;
mtData.cmd = cmd;
mtData.dataSize = dataSize;
if (data != 0)
{
mtData.data = new BYTE[dataSize];
if (mtData.data == 0){ return; }
memcpy(mtData.data, data, dataSize);
}
m_DataQueues.push_back(mtData);
}
// 处理消息
void post(float dt)
{
std::lock_guard<std::mutex> lk(m_Mutex); //线程开始加锁,退出时自动解锁
while (!m_DataQueues.empty())
{
const MTData& mtData = m_DataQueues.front();
if (mtData.onwer < __SocketIndex)
{
CSocketEngine* owner = __SocketMap[mtData.onwer];
if (owner)
{
if (mtData.cmd == EVENT_TCP_SOCKET_LINK) owner->OnSocketLink(mtData.dataSize);
else if (mtData.cmd == EVENT_TCP_SOCKET_READ) owner->OnSocketRead(mtData.data, mtData.dataSize);
else if (mtData.cmd == EVENT_TCP_SOCKET_SHUT) owner->CloseSocket(mtData.dataSize);
}
if (mtData.data) delete[]mtData.data;
}
m_DataQueues.pop_front();
}
}
};
//////////////////////////////////////////////////////////////////////////
MTSocketQueue* MTSocketQueue::m_sInstance = 0;
//////////////////////////////////////////////////////////////////////////
void CSocketEngine::PerformConnectThread(std::string szServerIP, WORD wPort, int nSocketIndex)
{
if (nSocketIndex > __SocketCount) return;
struct addrinfo * res = NULL;
char szPort[10]={0};
sprintf(szPort,"%d",wPort);
int error = getaddrinfo(szServerIP.c_str(), szPort, NULL, &res);
if (error != 0)
{
CCLOG("域名解析失败,[%s] line [%d] error in ServerIP[%s], Port[%d], getaddrinfo:%d, strErr=%s",
__FUNCTION__, __LINE__, szServerIP.c_str(), wPort, error, gai_strerror(error));
if (GetMTSocketQueue) GetMTSocketQueue->PostAsynEventData(nSocketIndex, EVENT_TCP_SOCKET_SHUT, 0, SHUT_REASON_EXCEPTION); return;
return;
}
if (__SocketMap[nSocketIndex]) __SocketMap[nSocketIndex]->m_hSocket = socket(res->ai_family,SOCK_STREAM,0);
if (__SocketMap[nSocketIndex] && __SocketMap[nSocketIndex]->m_hSocket < 0)
{
CCLOG("TcpClientSocket::function [%s] line [%d]", __FUNCTION__, __LINE__);
if (GetMTSocketQueue) GetMTSocketQueue->PostAsynEventData(nSocketIndex, EVENT_TCP_SOCKET_SHUT, 0, SHUT_REASON_EXCEPTION); return;
}
if (__SocketMap[nSocketIndex] && connect(__SocketMap[nSocketIndex]->m_hSocket, res->ai_addr, res->ai_addrlen) < 0)
{
CCLOG("Socket::%s connect err... line [%d]", __FUNCTION__, __LINE__);
if (GetMTSocketQueue) GetMTSocketQueue->PostAsynEventData(nSocketIndex, EVENT_TCP_SOCKET_SHUT, 0, SHUT_REASON_EXCEPTION); return;
}
freeaddrinfo(res);
int nSendtimeout = 3000; //3s
if (__SocketMap[nSocketIndex]) setsockopt(__SocketMap[nSocketIndex]->m_hSocket, SOL_SOCKET, SO_SNDTIMEO, (const char*)&nSendtimeout, sizeof(nSendtimeout));
int nRecvtimeout = 21000; //21s
if (__SocketMap[nSocketIndex]) setsockopt(__SocketMap[nSocketIndex]->m_hSocket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&nRecvtimeout, sizeof(nRecvtimeout));
if (__SocketMap[nSocketIndex])__SocketMap[nSocketIndex]->m_wSocketID = (WORD)__SocketMap[nSocketIndex]->m_hSocket;
std::thread tThread(&CSocketEngine::PerformRecvectThread, nSocketIndex);
tThread.detach();
}
// 客户端线程接收连接
void CSocketEngine::PerformRecvectThread(int nSocketIndex)
{
if (nSocketIndex > __SocketCount) return;
if (__SocketMap[nSocketIndex]) std::lock_guard<std::mutex> lk(__SocketMap[nSocketIndex]->m_MutexRecv); //线程开始加锁,退出时自动解锁
if (__SocketMap[nSocketIndex]) __SocketMap[nSocketIndex]->m_cbSocketStatus = SOCKET_STATUS_CONNECT;
if (__SocketMap[nSocketIndex] && GetMTSocketQueue) GetMTSocketQueue->PostAsynEventData(nSocketIndex, EVENT_TCP_SOCKET_LINK, 0, SOCKET_STATUS_CONNECT);
socket_sleep(10);
while (__SocketMap[nSocketIndex] && __SocketMap[nSocketIndex]->GetSocketStatus() == SOCKET_STATUS_CONNECT)
{
char cbRecvBuf[SOCKET_TCP_BUFFER] = { 0 }; //接收缓冲
if (!__SocketMap[nSocketIndex]) continue;
int nDataSize = socket_recv(__SocketMap[nSocketIndex]->m_hSocket, cbRecvBuf, SOCKET_TCP_BUFFER);
if (SOCKET_ERROR == nDataSize)
{
int errCode = socket_error();
//CCLOG("recv failed %d !", errCode);
//无法立即完成非阻塞Socket上的操作
if (errCode == 10004) break;
else if (errCode == LHS_EWOULDBLOCK)
{
socket_sleep(20);
CCLOG("waiting back msg!\n");
continue;
}
else if (errCode == LHS_EAGAIN)
{
continue;
}
if (GetMTSocketQueue) GetMTSocketQueue->PostAsynEventData(nSocketIndex, EVENT_TCP_SOCKET_SHUT, 0, SHUT_REASON_EXCEPTION);
return;
}
if (nDataSize == 0) break;
if (GetMTSocketQueue) GetMTSocketQueue->PostAsynEventData(nSocketIndex, EVENT_TCP_SOCKET_READ, cbRecvBuf, nDataSize);
}
if (__SocketMap[nSocketIndex] && __SocketMap[nSocketIndex]->m_hSocket != INVALID_SOCKET && GetMTSocketQueue) GetMTSocketQueue->PostAsynEventData(nSocketIndex, EVENT_TCP_SOCKET_SHUT, 0, SHUT_REASON_NORMAL);
}
//////////////////////////////////////////////////////////////////////////
// 构造函数
CSocketEngine::CSocketEngine()
{
// 辅助变量
m_wSocketID = INVALID_WORD;
m_SocketIndex = -1;
m_cbSocketStatus = SOCKET_STATUS_IDLE; // 网络状态
m_dwSendTickCount = INVALID_DWORD; // 发送时间
m_dwRecvTickCount = INVALID_DWORD; // 接收时间
m_wRecvSize = 0; // 接收长度
ZeroMemory(m_cbRecvBuf, sizeof(m_cbRecvBuf)); // 接收缓冲
m_hSocket = INVALID_SOCKET; // 连接句柄
m_pITCPSocketSink = nullptr; // 回调接口
}
// 析构函数
CSocketEngine::~CSocketEngine()
{
__SocketMap[m_SocketIndex] = 0;
m_pITCPSocketSink = nullptr; // 回调接口
CloseSocket(SHUT_REASON_NORMAL);
}
// 设置接口
bool CSocketEngine::SetTCPSocketSink(ITCPSocketSink* pIUnknownEx)
{
m_pITCPSocketSink = pIUnknownEx;
return (m_pITCPSocketSink != NULL);
}
// 连接服务器
BYTE CSocketEngine::Connect(std::string szServerIP, WORD wPort)
{
// 效验数据
if (szServerIP.empty() || (wPort == 0)) return CONNECT_FAILURE;
m_cbSocketStatus = SOCKET_STATUS_WAIT;
if (m_SocketIndex == -1)
{
m_SocketIndex = __SocketIndex++;
__SocketMap[m_SocketIndex] = this;
if (__SocketIndex >= __SocketCount)__SocketIndex = 0;
}
std::thread tThread(&CSocketEngine::PerformConnectThread, szServerIP, wPort, m_SocketIndex);
tThread.detach();
return CONNECT_SUCCESS;
}
// 发送函数
WORD CSocketEngine::SendData(WORD wMainCmdID, WORD wSubCmdID)
{
// 效验状态
if (m_hSocket == INVALID_SOCKET) return false;
if (m_cbSocketStatus != SOCKET_STATUS_CONNECT) return false;
// 构造数据
BYTE cbDataBuffer[SOCKET_TCP_BUFFER];
TCP_Head* pHead = (TCP_Head*)cbDataBuffer;
pHead->CommandInfo.wMainCmdID = wMainCmdID;
pHead->CommandInfo.wSubCmdID = wSubCmdID;
// 加密数据
WORD wSendSize = EncryptBuffer(cbDataBuffer, sizeof(TCP_Head), sizeof(cbDataBuffer));
// 发送数据
return SendDataBuffer(cbDataBuffer, wSendSize) != 0;
}
// 发送函数
WORD CSocketEngine::SendData(WORD wMainCmdID, WORD wSubCmdID, void* pData, WORD wDataSize)
{
// 效验状态
if (m_hSocket == INVALID_SOCKET) return false;
if (m_cbSocketStatus != SOCKET_STATUS_CONNECT) return false;
// 效验大小
ASSERT(wDataSize <= SOCKET_TCP_PACKET);
if (wDataSize > SOCKET_TCP_PACKET) return false;
BYTE cbDataBuffer[SOCKET_TCP_BUFFER];
TCP_Head* pHead = (TCP_Head*)cbDataBuffer;
pHead->CommandInfo.wMainCmdID = wMainCmdID;
pHead->CommandInfo.wSubCmdID = wSubCmdID;
if (wDataSize > 0)
{
ASSERT(pData != NULL);
CopyMemory(pHead + 1, pData, wDataSize);
}
// 加密数据
WORD wSendSize = EncryptBuffer(cbDataBuffer, sizeof(TCP_Head) + wDataSize, sizeof(cbDataBuffer));
// 发送数据
return SendDataBuffer(cbDataBuffer, wSendSize);
}
// 关闭连接
VOID CSocketEngine::CloseSocket()
{
CloseSocket(SHUT_REASON_NORMAL);
}
// 连接事件
void CSocketEngine::OnSocketLink(int nErrorCode)
{
if (m_pITCPSocketSink) m_pITCPSocketSink->OnEventTCPSocketLink(m_wSocketID, nErrorCode);
}
// 发送数据
WORD CSocketEngine::SendDataBuffer(void* pBuffer, WORD wSendSize)
{
// 效验参数
ASSERT(wSendSize != 0);
ASSERT(pBuffer != NULL);
// 发送数据
WORD wSended = 0;
while (wSended < wSendSize)
{
while (true)
{
int retVal = socket_send(m_hSocket, (char*)pBuffer + wSended, wSendSize - wSended);
if (SOCKET_ERROR == retVal)
{
if (socket_error() == LHS_EWOULDBLOCK)
{
//无法立即完成非阻塞Socket上的操作
socket_sleep(5);
continue;
}
else
{
CCLOG("send failed %d!\n", socket_error());
if (GetMTSocketQueue) GetMTSocketQueue->PostAsynEventData(m_SocketIndex, EVENT_TCP_SOCKET_SHUT, 0, SHUT_REASON_EXCEPTION);
return 0;
}
}
wSended += retVal;
break;
}
}
m_dwSendTickCount = socket_TickCount();
return wSended;
}
// 网络消息
void CSocketEngine::OnSocketRead(void* pBuffer, WORD wSendSize)
{
try
{
CopyMemory(&m_cbRecvBuf[m_wRecvSize], pBuffer, wSendSize);
m_wRecvSize += wSendSize;
DWORD dwLong = socket_TickCount() - m_dwRecvTickCount;
//CCLOG("---------- %d ms", dwLong);
m_dwRecvTickCount = socket_TickCount();
// 变量定义
WORD wPacketSize = 0;
BYTE cbDataBuffer[SOCKET_TCP_BUFFER] = { 0 };
TCP_Head* pHead = (TCP_Head*)m_cbRecvBuf;
while (m_wRecvSize >= sizeof(TCP_Head) && m_cbSocketStatus == SOCKET_STATUS_CONNECT)
{
// 效验参数
wPacketSize = pHead->TCPInfo.wPacketSize;
ASSERT(pHead->TCPInfo.cbDataKind == DK_MAPPED);
ASSERT(wPacketSize <= SOCKET_TCP_BUFFER);
if (pHead->TCPInfo.cbDataKind != DK_MAPPED)
{
cocos2d::MessageBox("只支持加密映射", "");
throw "只支持映射加密";
}
if (wPacketSize > SOCKET_TCP_BUFFER)
{
cocos2d::MessageBox("只支持加密映射", "");
throw "数据包太大";
}
if (m_wRecvSize < wPacketSize) return;
// 拷贝数据
CopyMemory(cbDataBuffer, m_cbRecvBuf, wPacketSize);
m_wRecvSize -= wPacketSize;
MoveMemory(m_cbRecvBuf, m_cbRecvBuf + wPacketSize, m_wRecvSize);
// 解密数据
WORD wRealySize = CrevasseBuffer(cbDataBuffer, wPacketSize);
ASSERT(wRealySize >= sizeof(TCP_Head));
// 解释数据
WORD 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)
{
// 发送数据
SendData(MDM_KN_COMMAND, SUB_KN_DETECT_SOCKET, pDataBuffer, wDataSize);
continue;
}
// 处理数据
bool bSuccess = m_pITCPSocketSink->OnEventTCPSocketRead(m_wSocketID, Command, pDataBuffer, wDataSize);
if (bSuccess == false) throw "网络数据包处理失败";
}
}
catch (...)
{
CloseSocket(SHUT_REASON_EXCEPTION);
}
}
// 关闭连接
VOID CSocketEngine::CloseSocket(BYTE cbShutReason)
{
// 关闭连接
if (m_hSocket != INVALID_SOCKET)
{
socket_close(m_hSocket);
m_hSocket = INVALID_SOCKET;
m_cbSocketStatus = SOCKET_STATUS_IDLE;
if (m_SocketIndex != -1 && __SocketMap[m_SocketIndex]) __SocketMap[m_SocketIndex] = 0;
m_SocketIndex = -1;
}
if (m_pITCPSocketSink)
{
try { m_pITCPSocketSink->OnEventTCPSocketShut(m_wSocketID, cbShutReason); }
catch (...) {}
}
// 恢复数据
m_wRecvSize = 0;
m_dwSendTickCount = 0;
m_dwRecvTickCount = 0;
}
// 加密数据
WORD CSocketEngine::EncryptBuffer(BYTE pcbDataBuffer[], WORD wDataSize, WORD wBufferSize)
{
// 效验参数
CC_ASSERT(wDataSize >= sizeof(TCP_Head));
CC_ASSERT(wBufferSize >= wDataSize);
CC_ASSERT(wDataSize <= SOCKET_TCP_BUFFER);
// 效验码与字节映射
BYTE cbCheckCode = 0;
for (WORD i = sizeof(TCP_Info); i < wDataSize; i++)
{
cbCheckCode += pcbDataBuffer[i];
pcbDataBuffer[i] = g_SendByteMap[pcbDataBuffer[i]];
}
// 填写信息头
TCP_Head* pHead = (TCP_Head*)pcbDataBuffer;
pHead->TCPInfo.cbCheckCode = ~cbCheckCode + 1;
pHead->TCPInfo.wPacketSize = wDataSize;
pHead->TCPInfo.cbDataKind = DK_MAPPED;
return wDataSize;
}
// 解密数据
WORD CSocketEngine::CrevasseBuffer(BYTE pcbDataBuffer[], WORD wDataSize)
{
// 效验参数
CC_ASSERT(wDataSize >= sizeof(TCP_Head));
CC_ASSERT(((TCP_Head*)pcbDataBuffer)->TCPInfo.wPacketSize == wDataSize);
// 效验码与字节映射
TCP_Head* pHead = (TCP_Head*)pcbDataBuffer;
BYTE cbCheckCode = pHead->TCPInfo.cbCheckCode;
for (int i = sizeof(TCP_Info); i < wDataSize; i++)
{
pcbDataBuffer[i] = g_RecvByteMap[pcbDataBuffer[i]];
cbCheckCode += pcbDataBuffer[i];
}
if (cbCheckCode != 0) { CC_ASSERT(false || "数据包效验码错误"); }
return wDataSize;
}
//////////////////////////////////////////////////////////////////////////
//bool TcpClientSocket::subConnectServerIPV6(const char *pServerIP, unsigned short ServerPort)
//{
// CCLog("TcpClientSocket::function [%s] line [%d]", __FUNCTION__, __LINE__);
// struct sockaddr_in6 addrServer;
// int tempSocket = -1;
//
// memset(&addrServer, 0, sizeof(addrServer));
// addrServer.sin6_family = AF_INET6;
// addrServer.sin6_port = htons(ServerPort);
// inet_pton(AF_INET6, pServerIP, &addrServer.sin6_addr);
// if ((tempSocket = socket(AF_INET6, SOCK_STREAM, 0)) < 0)
// {
// state = NETWORK_STATE_FAILED;
// CCLog("TcpClientSocket::%s socket err... line [%d]", __FUNCTION__, __LINE__);
// return false;
// }
//
// if (connect(tempSocket, (struct sockaddr*)&addrServer, sizeof(addrServer)) < 0)
// {
// CCLog("TcpClientSocket::%s connect err... line [%d]", __FUNCTION__, __LINE__);
//
// return false;
// }
// return true;
//}