博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
包含到cocos2d-x里的tcpsocket源码
阅读量:5908 次
发布时间:2019-06-19

本文共 50247 字,大约阅读时间需要 167 分钟。

声明:本文参考了发布的blog“

Socket处理是异步非阻塞的,所以可以放心的放到主线程处理消息,并且在原作者的基本上进行了系列优化,考虑了客户端可能建立多个SOCKET,因此加入了Manager概念,与cocos2d-x进行了融合。

本文基于cocos2d-x3.0+VS2012

文件目录结构截图:

 

文件源码:

TCPSocket.h

1 #ifndef __CC_TCPSOCKET_H__  2 #define __CC_TCPSOCKET_H__  3   4 #include "cocos2d.h"  5 #include "ExtensionMacros.h"  6 #include "WorldPacket.h"  7 #ifdef WIN32  8 #include 
9 #include
10 #pragma comment( lib, "ws2_32.lib" ) 11 #else 12 #include
13 #include
14 #include
15 #include
16 #include
17 18 #define SOCKET int 19 #define SOCKET_ERROR -1 20 #define INVALID_SOCKET -1 21 22 #endif 23 24 NS_CC_EXT_BEGIN 25 #ifndef CHECKF 26 #define CHECKF(x) \ 27 do \ 28 { \ 29 if (!(x)) { \ 30 log_msg("CHECKF", #x, __FILE__, __LINE__); \ 31 return 0; \ 32 } \ 33 } while (0) 34 #endif 35 36 #define _MAX_MSGSIZE 16 * 1024 // 暂定一个消息最大为16k 37 #define BLOCKSECONDS 30 // INIT函数阻塞时间 38 #define INBUFSIZE (64*1024) //? 具体尺寸根据剖面报告调整 接收数据的缓存 39 #define OUTBUFSIZE (8*1024) //? 具体尺寸根据剖面报告调整。 发送数据的缓存,当不超过8K时,FLUSH只需要SEND一次 40 41 class CC_DLL TCPSocket 42 { 43 public: 44 TCPSocket(void); 45 bool Create(const char* pszServerIP, int nServerPort, int tagid, int nBlockSec = BLOCKSECONDS, bool bKeepAlive = false); 46 bool SendMsg(void* pBuf, int nSize); 47 bool ReceiveMsg(void* pBuf, int& nSize); 48 bool Flush(void); 49 bool Check(void); 50 void Destroy(void); 51 SOCKET GetSocket(void) const { return m_sockClient; } 52 53 int getTagID(){ return m_tag; } 54 private: 55 bool recvFromSock(void); // 从网络中读取尽可能多的数据 56 bool hasError(); // 是否发生错误,注意,异步模式未完成非错误 57 void closeSocket(); 58 59 SOCKET m_sockClient; 60 61 // 发送数据缓冲 62 char m_bufOutput[OUTBUFSIZE]; //? 可优化为指针数组 63 int m_nOutbufLen; 64 65 // 环形缓冲区 66 char m_bufInput[INBUFSIZE]; 67 int m_nInbufLen; 68 int m_nInbufStart; // INBUF使用循环式队列,该变量为队列起点,0 - (SIZE-1) 69 int m_tag; 70 }; 71 72 typedef std::function
ProAllFunc; // 接收所有协议,自行处理,@socket标识,@协议头,@数据包,返回是否分发 73 typedef std::function
ProFunc; // 接收单个协议,@socket标识,@数据包 74 typedef std::function
sckFunc; // 连接成功/断开事件 75 76 #define SCT_CALLBACK_1(func, _Object) std::bind(&func,_Object, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3) 77 #define SCT_CALLBACK_2(func, _Object) std::bind(&func,_Object, std::placeholders::_1, std::placeholders::_2) 78 #define SCT_CALLBACK_3(func, _Object) std::bind(&func,_Object, std::placeholders::_1) 79 // 创建SOCKET管理器 80 #define CREATE_TCPSOCKETMGR(pNode) pNode->addChild(new TCPSocketManager(), 0) 81 82 class CC_DLL TCPSocketManager : 83 public Node 84 { 85 public: 86 TCPSocketManager() 87 { 88 assert(!mSingleton); 89 this->mSingleton = this; 90 // 开启update 91 scheduleUpdate(); 92 }; 93 ~TCPSocketManager(){}; 94 // 创建socket并添加到管理器 95 TCPSocket *createSocket(const char* pszServerIP, // IP地址 96 int nServerPort, // 端口 97 int _tag, // 标识ID 98 int nBlockSec = BLOCKSECONDS, // 阻塞时间ms 99 bool bKeepAlive = false);100 // 注册协议包101 void register_process(const uint16 &entry, ProFunc callback);102 // 注册接收所有协议103 void register_all_process(ProAllFunc callback){ _pProcess = callback; }104 // 注册socket连接成功事件105 void register_connect(sckFunc callback){ _pOnConnect = callback; }106 // 注册socket断线事件107 void register_disconnect(sckFunc callback){ _OnDisconnect = callback; }108 109 // 单独添加socket到管理器110 bool addSocket(TCPSocket *pSocket);111 // 删除socket112 bool removeSocket(int _tag);113 // 断开socket114 void disconnect(int _tag);115 // 获取socket116 TCPSocket *GetSocket(int _tag);117 // 发送消息118 bool SendPacket(int _tag, WorldPacket *packet);119 120 void update(float delta);121 122 static TCPSocketManager &getSingleton(){ assert(mSingleton); return *mSingleton;}123 124 private: 125 ProAllFunc _pProcess;126 sckFunc _pOnConnect;127 sckFunc _OnDisconnect;128 std::list
m_lstSocket;129 std::map
_mapProcess;130 static TCPSocketManager * mSingleton;131 };132 133 #define sSocketMgr TCPSocketManager::getSingleton()134 NS_CC_EXT_END135 136 #endif //__CC_TCPSOCKET_H__

TCPSocket.cpp

#include "TCPSocket.h"#include "support/zip_support/unzip.h"NS_CC_EXT_BEGINTCPSocket::TCPSocket(){     // 初始化    memset(m_bufOutput, 0, sizeof(m_bufOutput));    memset(m_bufInput, 0, sizeof(m_bufInput));}void TCPSocket::closeSocket(){#ifdef WIN32    closesocket(m_sockClient);    WSACleanup();#else    close(m_sockClient);#endif}bool TCPSocket::Create(const char* pszServerIP, int nServerPort, int tagid, int nBlockSec, bool bKeepAlive /*= FALSE*/){    // 检查参数    if(pszServerIP == 0 || strlen(pszServerIP) > 15) {        return false;    }#ifdef WIN32    WSADATA wsaData;    WORD version = MAKEWORD(2, 0);    int ret = WSAStartup(version, &wsaData);//win sock start up    if (ret != 0) {        return false;    }#endif    // 创建主套接字    m_sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    if(m_sockClient == INVALID_SOCKET) {        closeSocket();        return false;    }    // 设置SOCKET为KEEPALIVE    if(bKeepAlive)    {        int        optval=1;        if(setsockopt(m_sockClient, SOL_SOCKET, SO_KEEPALIVE, (char *) &optval, sizeof(optval)))        {            closeSocket();            return false;        }    }#ifdef WIN32    DWORD nMode = 1;    int nRes = ioctlsocket(m_sockClient, FIONBIO, &nMode);    if (nRes == SOCKET_ERROR) {        closeSocket();        return false;    }#else    // 设置为非阻塞方式    fcntl(m_sockClient, F_SETFL, O_NONBLOCK);#endif    unsigned long serveraddr = inet_addr(pszServerIP);    if(serveraddr == INADDR_NONE)    // 检查IP地址格式错误    {        closeSocket();        return false;    }    sockaddr_in    addr_in;    memset((void *)&addr_in, 0, sizeof(addr_in));    addr_in.sin_family = AF_INET;    addr_in.sin_port = htons(nServerPort);    addr_in.sin_addr.s_addr = serveraddr;        if(connect(m_sockClient, (sockaddr *)&addr_in, sizeof(addr_in)) == SOCKET_ERROR) {        if (hasError()) {            closeSocket();            return false;        }        else    // WSAWOLDBLOCK        {            timeval timeout;            timeout.tv_sec    = nBlockSec;            timeout.tv_usec    = 0;            fd_set writeset, exceptset;            FD_ZERO(&writeset);            FD_ZERO(&exceptset);            FD_SET(m_sockClient, &writeset);            FD_SET(m_sockClient, &exceptset);            int ret = select(FD_SETSIZE, NULL, &writeset, &exceptset, &timeout);            if (ret == 0 || ret < 0) {                closeSocket();                return false;            } else    // ret > 0            {                ret = FD_ISSET(m_sockClient, &exceptset);                if(ret)        // or (!FD_ISSET(m_sockClient, &writeset)                {                    closeSocket();                    return false;                }            }        }    }    m_nInbufLen        = 0;    m_nInbufStart    = 0;    m_nOutbufLen    = 0;    struct linger so_linger;    so_linger.l_onoff = 1;    so_linger.l_linger = 500;    setsockopt(m_sockClient, SOL_SOCKET, SO_LINGER, (const char*)&so_linger, sizeof(so_linger));    m_tag = tagid;    return true;}bool TCPSocket::SendMsg(void* pBuf, int nSize){    if(pBuf == 0 || nSize <= 0) {        return false;    }    if (m_sockClient == INVALID_SOCKET) {        return false;    }    // 检查通讯消息包长度    int packsize = 0;    packsize = nSize;    // 检测BUF溢出    if(m_nOutbufLen + nSize > OUTBUFSIZE) {        // 立即发送OUTBUF中的数据,以清空OUTBUF。        Flush();        if(m_nOutbufLen + nSize > OUTBUFSIZE) {            // 出错了            Destroy();            return false;        }    }    // 数据添加到BUF尾    memcpy(m_bufOutput + m_nOutbufLen, pBuf, nSize);    m_nOutbufLen += nSize;    return true;}bool TCPSocket::ReceiveMsg(void* pBuf, int& nSize){    //检查参数    if(pBuf == NULL || nSize <= 0) {        return false;    }        if (m_sockClient == INVALID_SOCKET) {        return false;    }    // 检查是否有一个消息(小于2则无法获取到消息长度)    if(m_nInbufLen < 2) {        //  如果没有请求成功  或者   如果没有数据则直接返回        if(!recvFromSock() || m_nInbufLen < 2) {        // 这个m_nInbufLen更新了            return false;        }    }    // 计算要拷贝的消息的大小(一个消息,大小为整个消息的第一个16字节),因为环形缓冲区,所以要分开计算    int packsize = (unsigned char)m_bufInput[m_nInbufStart+2] +        (unsigned char)m_bufInput[(m_nInbufStart + 3) % INBUFSIZE] * 256; // 注意字节序,高位+低位    // 检测消息包尺寸错误 暂定最大16k    if (packsize <= 0 || packsize > _MAX_MSGSIZE) {        m_nInbufLen = 0;        // 直接清空INBUF        m_nInbufStart = 0;        return false;    }    // 检查消息是否完整(如果将要拷贝的消息大于此时缓冲区数据长度,需要再次请求接收剩余数据)    if (packsize > m_nInbufLen) {        // 如果没有请求成功   或者    依然无法获取到完整的数据包  则返回,直到取得完整包        if (!recvFromSock() || packsize > m_nInbufLen) {    // 这个m_nInbufLen已更新            return false;        }    }    // 复制出一个消息    if(m_nInbufStart + packsize > INBUFSIZE) {        // 如果一个消息有回卷(被拆成两份在环形缓冲区的头尾)        // 先拷贝环形缓冲区末尾的数据        int copylen = INBUFSIZE - m_nInbufStart;        memcpy(pBuf, m_bufInput + m_nInbufStart, copylen);        // 再拷贝环形缓冲区头部的剩余部分        memcpy((unsigned char *)pBuf + copylen, m_bufInput, packsize - copylen);        nSize = packsize;    } else {        // 消息没有回卷,可以一次拷贝出去        memcpy(pBuf, m_bufInput + m_nInbufStart, packsize);        nSize = packsize;    }    // 重新计算环形缓冲区头部位置    m_nInbufStart = (m_nInbufStart + packsize) % INBUFSIZE;    m_nInbufLen -= packsize;    return    true;}bool TCPSocket::hasError(){#ifdef WIN32    int err = WSAGetLastError();    if(err != WSAEWOULDBLOCK) {#else    int err = errno;    if(err != EINPROGRESS && err != EAGAIN) {#endif        return true;    }    return false;}// 从网络中读取尽可能多的数据,实际向服务器请求数据的地方bool TCPSocket::recvFromSock(void){    if (m_nInbufLen >= INBUFSIZE || m_sockClient == INVALID_SOCKET) {        return false;    }    // 接收第一段数据    int    savelen, savepos;            // 数据要保存的长度和位置    if(m_nInbufStart + m_nInbufLen < INBUFSIZE)    {    // INBUF中的剩余空间有回绕        savelen = INBUFSIZE - (m_nInbufStart + m_nInbufLen);        // 后部空间长度,最大接收数据的长度    } else {        savelen = INBUFSIZE - m_nInbufLen;    }    // 缓冲区数据的末尾    savepos = (m_nInbufStart + m_nInbufLen) % INBUFSIZE;    //CHECKF(savepos + savelen <= INBUFSIZE);    int inlen = recv(m_sockClient, m_bufInput + savepos, savelen, 0);    if(inlen > 0) {        // 有接收到数据        m_nInbufLen += inlen;                if (m_nInbufLen > INBUFSIZE) {            return false;        }        // 接收第二段数据(一次接收没有完成,接收第二段数据)        if(inlen == savelen && m_nInbufLen < INBUFSIZE) {            int savelen = INBUFSIZE - m_nInbufLen;            int savepos = (m_nInbufStart + m_nInbufLen) % INBUFSIZE;            //CHECKF(savepos + savelen <= INBUFSIZE);            inlen = recv(m_sockClient, m_bufInput + savepos, savelen, 0);            if(inlen > 0) {                m_nInbufLen += inlen;                if (m_nInbufLen > INBUFSIZE) {                    return false;                }                } else if(inlen == 0) {                Destroy();                return false;            } else {                // 连接已断开或者错误(包括阻塞)                if (hasError()) {                    Destroy();                    return false;                }            }        }    } else if(inlen == 0) {        Destroy();        return false;    } else {        // 连接已断开或者错误(包括阻塞)        if (hasError()) {            Destroy();            return false;        }    }    return true;}bool TCPSocket::Flush(void)        //? 如果 OUTBUF > SENDBUF 则需要多次SEND(){    if (m_sockClient == INVALID_SOCKET) {        return false;    }    if(m_nOutbufLen <= 0) {        return true;    }        // 发送一段数据    int    outsize;    outsize = send(m_sockClient, m_bufOutput, m_nOutbufLen, 0);    if(outsize > 0) {        // 删除已发送的部分        if(m_nOutbufLen - outsize > 0) {            memcpy(m_bufOutput, m_bufOutput + outsize, m_nOutbufLen - outsize);        }        m_nOutbufLen -= outsize;        if (m_nOutbufLen < 0) {            return false;        }    } else {        if (hasError()) {            Destroy();            return false;        }    }    return true;}bool TCPSocket::Check(void){    // 检查状态    if (m_sockClient == INVALID_SOCKET) {        return false;    }    char buf[1];    int    ret = recv(m_sockClient, buf, 1, MSG_PEEK);    if(ret == 0) {        Destroy();        return false;    } else if(ret < 0) {        if (hasError()) {            Destroy();            return false;        } else {    // 阻塞            return true;        }    } else {    // 有数据        return true;    }        return true;}void TCPSocket::Destroy(void){    // 关闭    struct linger so_linger;    so_linger.l_onoff = 1;    so_linger.l_linger = 500;    int ret = setsockopt(m_sockClient, SOL_SOCKET, SO_LINGER, (const char*)&so_linger, sizeof(so_linger));    closeSocket();    m_sockClient = INVALID_SOCKET;    m_nInbufLen = 0;    m_nInbufStart = 0;    m_nOutbufLen = 0;    memset(m_bufOutput, 0, sizeof(m_bufOutput));    memset(m_bufInput, 0, sizeof(m_bufInput));}TCPSocketManager *TCPSocketManager::mSingleton = 0;TCPSocket *TCPSocketManager::createSocket(const char* pszServerIP,    // IP地址                            int nServerPort,            // 端口                            int _tag,                    // 标识ID                            int nBlockSec,            // 阻塞时间ms                            bool bKeepAlive){    TCPSocket *pSocket = new TCPSocket();    if (pSocket->Create(pszServerIP, nServerPort, _tag, nBlockSec, bKeepAlive))    {        assert(addSocket(pSocket));        if (_pOnConnect){            _pOnConnect(_tag);        }        return pSocket;    }    delete pSocket;    return NULL;}bool    TCPSocketManager::addSocket(TCPSocket *pSocket){    std::list
::iterator iter, enditer = m_lstSocket.end(); for (iter = m_lstSocket.begin(); iter != enditer; ++ iter) { if ((*iter)->GetSocket() == pSocket->GetSocket()) return false; } m_lstSocket.push_back(pSocket); return true;}// 删除socketbool TCPSocketManager::removeSocket(int _tag){ std::list
::iterator iter, enditer = m_lstSocket.end(); for (iter = m_lstSocket.begin(); iter != enditer; ++ iter) { if ((*iter)->getTagID() == _tag) { (*iter)->Destroy(); m_lstSocket.erase(iter); return true; } } return false;}TCPSocket *TCPSocketManager::GetSocket(int _tag){ std::list
::iterator iter, enditer = m_lstSocket.end(); for (iter = m_lstSocket.begin(); iter != enditer; ++ iter) { if ((*iter)->getTagID() == _tag) { return *iter; } } return NULL;}void TCPSocketManager::update(float delta){ std::list
::iterator iter, enditer = m_lstSocket.end(); for (iter = m_lstSocket.begin(); iter != enditer; ++ iter) { TCPSocket *pSocket = *iter; int _tag = pSocket->getTagID(); if (!pSocket->Check()) {
// 掉线了 _OnDisconnect(_tag); m_lstSocket.erase(iter); break; } while (true) { char buffer[_MAX_MSGSIZE] = {
0}; int nSize = sizeof(buffer); char *pbufMsg = buffer; if (!pSocket->ReceiveMsg(pbufMsg, nSize)) break; WorldPacket packet; uint16 _cmd, _length; packet.Write((uint8*)pbufMsg, nSize); packet >> _cmd >> _length; if (_cmd & 0x8000) { Byte uncompr[1024] = {
0}; uLong uncomprLen; _cmd &= 0x7fff; uncompress(uncompr, &uncomprLen, packet.contents()+4, packet.size()-4); } if (_pProcess == 0 || _pProcess(pSocket->getTagID(), _cmd, packet)) {
// 分发数据 std::map
::iterator mapi = _mapProcess.find(_cmd); if (mapi == _mapProcess.end()) continue; mapi->second(pSocket->getTagID(), packet); } } }}void TCPSocketManager::register_process(const uint16 &entry, ProFunc callback){ _mapProcess[entry] = callback;}bool TCPSocketManager::SendPacket(int _tag, WorldPacket *packet){ std::list
::iterator iter, enditer = m_lstSocket.end(); for (iter = m_lstSocket.begin(); iter != enditer; ++ iter) { if ((*iter)->getTagID() == _tag) { (*iter)->SendMsg((void *)packet->contents(), packet->size()); return (*iter)->Flush(); } } return false;}void TCPSocketManager::disconnect(int _tag){ std::list
::iterator iter, enditer = m_lstSocket.end(); for (iter = m_lstSocket.begin(); iter != enditer; ++ iter) { if ((*iter)->getTagID() == _tag) { (*iter)->Destroy(); if (_OnDisconnect){ _OnDisconnect(_tag); } break; } }}NS_CC_EXT_END

ByteBuffer.h  (读写数据包)

1 /****************************************************************************  2  *  3  * ByteBuffer Class  4 *  5  */  6   7 #ifndef _BYTEBUFFER_H  8 #define _BYTEBUFFER_H  9  10 #include "Common.h" 11 //#include "Vector3.h" 12  13 class  ByteBuffer 14 { 15 #define DEFAULT_SIZE 0x1000 16 #define DEFAULT_INCREASE_SIZE 200 17     uint8 * m_buffer; 18     size_t m_readPos; 19     size_t m_writePos; 20     uint32 m_buffersize; 21  22 public: 23     /** Creates a bytebuffer with the default size 24      */ 25     ByteBuffer() 26     { 27         m_buffer =0; 28         m_readPos = m_writePos = 0; 29         m_buffersize = 0; 30         reserve(DEFAULT_SIZE); 31     } 32  33     /** Creates a bytebuffer with the specified size 34      */ 35     ByteBuffer(size_t res) 36     { 37         m_buffer =0; 38         m_readPos = m_writePos = 0; 39         m_buffersize = 0; 40             reserve(res); 41     } 42  43     /** Frees the allocated buffer 44      */ 45     ~ByteBuffer() 46     { 47         free(m_buffer); 48     } 49  50  51     /** Allocates/reallocates buffer with specified size. 52      */ 53     void reserve(size_t res) 54     { 55         if(m_buffer) 56             m_buffer = (uint8*)realloc(m_buffer, res); 57         else 58             m_buffer = (uint8*)malloc(res); 59  60         m_buffersize = res; 61     } 62  63  64     /** Resets read/write indexes 65      */ 66     inline void clear() 67     { 68         m_readPos = m_writePos = 0; 69     } 70  71     /** Sets write position 72      */ 73     inline void resize(size_t size) 74     { 75         m_writePos = size; 76     } 77  78     /** Returns the buffer pointer 79      */ 80     inline const uint8 * contents() 81     { 82         return m_buffer; 83     } 84  85  86     /** Gets the buffer size. 87      */ 88     uint32 GetBufferSize() { return m_writePos; } 89  90     /** Reads sizeof(T) bytes from the buffer 91      * @return the bytes read 92      */ 93     template
94 T Read() 95 { 96 if(m_readPos + sizeof(T) > m_writePos) 97 return (T)0; 98 T ret = *(T*)&m_buffer[m_readPos]; 99 m_readPos += sizeof(T);100 return ret;101 }102 103 void skip(size_t len)104 {105 if(m_readPos + len > m_writePos)106 len = (m_writePos - m_readPos);107 m_readPos += len;108 }109 110 /** Reads x bytes from the buffer111 */112 void read(uint8 * buffer, size_t len)113 {114 if(m_readPos + len > m_writePos)115 len = (m_writePos - m_readPos);116 117 memcpy(buffer, &m_buffer[m_readPos], len);118 m_readPos += len;119 }120 121 /** Writes sizeof(T) bytes to the buffer, while checking for overflows.122 * @param T data The data to be written123 */124 template
125 void Write(const T & data)126 {127 size_t new_size = m_writePos + sizeof(T);128 if(new_size > m_buffersize)129 {130 new_size = (new_size / DEFAULT_INCREASE_SIZE + 1) * DEFAULT_INCREASE_SIZE;131 reserve(new_size);132 }133 134 *(T*)&m_buffer[m_writePos] = data;135 m_writePos += sizeof(T);136 }137 138 /** writes x bytes to the buffer, while checking for overflows139 * @param ptr the data to be written140 * @param size byte count141 */142 void Write(const uint8 * data, size_t size)143 {144 size_t new_size = m_writePos + size;145 if(new_size > m_buffersize)146 {147 new_size = (new_size / DEFAULT_INCREASE_SIZE + 1) * DEFAULT_INCREASE_SIZE;148 reserve(new_size);149 }150 151 memcpy(&m_buffer[m_writePos], data, size);152 m_writePos += size;153 }154 155 /** Ensures the buffer is big enough to fit the specified number of bytes.156 * @param bytes number of bytes to fit157 */158 inline void EnsureBufferSize(uint32 Bytes)159 {160 size_t new_size = m_writePos + Bytes;161 if(new_size > m_buffersize)162 {163 new_size = (new_size / DEFAULT_INCREASE_SIZE + 1) * DEFAULT_INCREASE_SIZE;164 reserve(new_size);165 }166 167 }168 169 /** These are the default read/write operators.170 */171 #define DEFINE_BUFFER_READ_OPERATOR(type) void operator >> (type& dest) { dest = Read
(); }172 #define DEFINE_BUFFER_WRITE_OPERATOR(type) void operator << (const type src) { Write
(src); }173 174 /** Fast read/write operators without using the templated read/write functions.175 */176 #define DEFINE_FAST_READ_OPERATOR(type, size) ByteBuffer& operator >> (type& dest) { if(m_readPos + size > m_writePos) { dest = (type)0; return *this; } else { dest = *(type*)&m_buffer[m_readPos]; m_readPos += size; return *this; } }177 #define DEFINE_FAST_WRITE_OPERATOR(type, size) ByteBuffer& operator << (const type src) { if(m_writePos + size > m_buffersize) { reserve(m_buffersize + DEFAULT_INCREASE_SIZE); } *(type*)&m_buffer[m_writePos] = src; m_writePos += size; return *this; }178 179 /** Integer/float r/w operators180 */181 DEFINE_FAST_READ_OPERATOR(uint64, 8);182 DEFINE_FAST_READ_OPERATOR(uint32, 4);183 DEFINE_FAST_READ_OPERATOR(uint16, 2);184 DEFINE_FAST_READ_OPERATOR(uint8, 1);185 DEFINE_FAST_READ_OPERATOR(int64, 8);186 DEFINE_FAST_READ_OPERATOR(int32, 4);187 DEFINE_FAST_READ_OPERATOR(int16, 2);188 DEFINE_FAST_READ_OPERATOR(int8, 1);189 DEFINE_FAST_READ_OPERATOR(float, 4);190 DEFINE_FAST_READ_OPERATOR(double, 8);191 192 DEFINE_FAST_WRITE_OPERATOR(uint64, 8);193 DEFINE_FAST_WRITE_OPERATOR(uint32, 4);194 DEFINE_FAST_WRITE_OPERATOR(uint16, 2);195 DEFINE_FAST_WRITE_OPERATOR(uint8, 1);196 DEFINE_FAST_WRITE_OPERATOR(int64, 8);197 DEFINE_FAST_WRITE_OPERATOR(int32, 4);198 DEFINE_FAST_WRITE_OPERATOR(int16, 2);199 DEFINE_FAST_WRITE_OPERATOR(int8, 1);200 DEFINE_FAST_WRITE_OPERATOR(float, 4);201 DEFINE_FAST_WRITE_OPERATOR(double, 8);202 203 /** boolean (1-byte) read/write operators204 */205 DEFINE_FAST_WRITE_OPERATOR(bool, 1);206 ByteBuffer& operator >> (bool & dst) { dst = (Read
() > 0 ? true : false); return *this; }207 208 /** string (null-terminated) operators209 */210 ByteBuffer& operator << (const std::string & value) { EnsureBufferSize(value.length() + 1); memcpy(&m_buffer[m_writePos], value.c_str(), value.length()+1); m_writePos += (value.length() + 1); return *this; }211 ByteBuffer& operator >> (std::string & dest)212 {213 dest.clear();214 char c;215 for(;;)216 {217 c = Read
();218 if(c == 0) break;219 dest += c;220 }221 return *this;222 }223 224 /** Gets the write position225 * @return buffer size226 */227 inline size_t size() { return m_writePos; }228 229 /** read/write position setting/getting230 */231 inline size_t rpos() { return m_readPos; }232 inline size_t wpos() { return m_writePos; }233 inline void rpos(size_t p) { assert(p <= m_writePos); m_readPos = p; }234 inline void wpos(size_t p) { assert(p <= m_buffersize); m_writePos = p; }235 236 template
size_t writeVector(std::vector
&v)237 {238 for (typename std::vector
::const_iterator i = v.begin(); i != v.end(); i++) {239 Write
(*i);240 }241 return v.size();242 243 }244 template
size_t readVector(size_t vsize, std::vector
&v)245 {246 247 v.clear();248 while(vsize--) {249 T t = Read
();250 v.push_back(t);251 }252 return v.size();253 }254 255 template
size_t writeList(std::list
&v)256 {257 for (typename std::list
::const_iterator i = v.begin(); i != v.end(); i++) {258 Write
(*i);259 }260 return v.size();261 262 }263 template
size_t readList(size_t vsize, std::list
&v)264 {265 266 v.clear();267 while(vsize--) {268 T t = Read
();269 v.push_back(t);270 }271 return v.size();272 }273 274 template
size_t writeMap(const std::map
&m)275 {276 for (typename std::map
::const_iterator i = m.begin(); i != m.end(); i++) {277 Write
(i->first);278 Write
(i->second);279 }280 return m.size();281 }282 283 template
size_t readMap(size_t msize, std::map
&m)284 {285 m.clear();286 while(msize--) {287 K k = Read
();288 V v = Read
();289 m.insert(make_pair(k, v));290 }291 return m.size();292 }293 294 };295 296 ///297 ///298 ///299 300 template
ByteBuffer &operator<<(ByteBuffer &b, const std::vector
& v)301 {302 b << (uint32)v.size();303 for (typename std::vector
::const_iterator i = v.begin(); i != v.end(); i++) {304 b << *i;305 }306 return b;307 }308 309 template
ByteBuffer &operator>>(ByteBuffer &b, std::vector
&v)310 {311 uint32 vsize;312 b >> vsize;313 v.clear();314 while(vsize--) {315 T t;316 b >> t;317 v.push_back(t);318 }319 return b;320 }321 322 template
ByteBuffer &operator<<(ByteBuffer &b, const std::list
& v)323 {324 b << (uint32)v.size();325 for (typename std::list
::const_iterator i = v.begin(); i != v.end(); i++) {326 b << *i;327 }328 return b;329 }330 331 template
ByteBuffer &operator>>(ByteBuffer &b, std::list
&v)332 {333 uint32 vsize;334 b >> vsize;335 v.clear();336 while(vsize--) {337 T t;338 b >> t;339 v.push_back(t);340 }341 return b;342 }343 344 template
ByteBuffer &operator<<(ByteBuffer &b, const std::map
&m)345 {346 b << (uint32)m.size();347 for (typename std::map
::const_iterator i = m.begin(); i != m.end(); i++) {348 b << i->first << i->second;349 }350 return b;351 }352 353 template
ByteBuffer &operator>>(ByteBuffer &b, std::map
&m)354 {355 uint32 msize;356 b >> msize;357 m.clear();358 while(msize--) {359 K k;360 V v;361 b >> k >> v;362 m.insert(make_pair(k, v));363 }364 return b;365 }366 367 #endif

WorldPacket.h  (读写扩展类,协议前2字节表示协议包,其次2字节表示数据大小)

1 #ifndef WGSERVER_WORLDPACKET_H  2 #define WGSERVER_WORLDPACKET_H  3   4   5 #include "ByteBuffer.h"  6   7   8 class WorldPacket : public ByteBuffer  9 { 10 public: 11     __inline WorldPacket() : ByteBuffer(), m_opcode(0) { } 12     __inline WorldPacket(uint16 opcode, size_t res) : ByteBuffer(res), m_opcode(opcode) {} 13     __inline WorldPacket(size_t res) : ByteBuffer(res), m_opcode(0) { } 14     __inline WorldPacket(const WorldPacket &packet) : ByteBuffer(packet), m_opcode(packet.m_opcode) {} 15  16     //! Clear packet and set opcode all in one mighty blow 17     __inline void Initialize(uint16 opcode ) 18     { 19         clear(); 20         m_opcode = opcode; 21     } 22  23     __inline uint16 GetOpcode() const { return m_opcode; } 24     __inline void SetOpcode(const uint16 & opcode) { m_opcode = opcode; } 25     __inline void SetLength(const uint16 & len)    {  26         uint16 * plen = (uint16 * ) &(contents()[2]); 27         *plen = len; 28     } 29  30     __inline std::string getString() 31     { 32         //std::string buff =  33         return (const char*)contents(); 34     } 35      36  template
37 void SetOffset(const uint16 & offset, const T value ) { 38 T * pval = (T *) &(contents()[offset]); 39 *pval = value; 40 } 41 42 public: 43 /** 44 * @创建时间 2011-08-31 45 * @创建人 李志勇 46 * @函数作用 向数据包追加字符串 47 * @参数 48 * @packet 数据封包指针 49 * @str 追加的字符串 50 */ 51 template
void AppendPacketString(std::string str) 52 { 53 T ilen = (T)str.size(); 54 *this << ilen; 55 if (ilen > 0) 56 Write((const uint8 *) str.c_str(), ilen); 57 } 58 /** 59 * @创建时间 2011-08-31 60 * @创建人 李志勇 61 * @函数作用 获取字符串 62 * @参数 63 * @packet 数据封包 64 * @返回 是否成功 65 */ 66 template
bool GetPacketString(std::string &str) 67 { 68 T ilen; 69 *this >> ilen; 70 if (ilen == 0) 71 return true; 72 uint8 buf[ilen+1]; 73 uint16 plen = size(); 74 if (plen < ilen) 75 return false; 76 read(buf, ilen); 77 buf[ilen] = 0; 78 str = (char*)buf; 79 return true; 80 } 81 82 83 protected: 84 uint16 m_opcode; 85 }; 86 87 /* 88 template
89 class SERVER_DECL StackWorldPacket : public StackBuffer
90 { 91 uint16 m_opcode; 92 public: 93 __inline StackWorldPacket(uint16 opcode) : StackBuffer
(), m_opcode(opcode) { } 94 95 //! Clear packet and set opcode all in one mighty blow 96 __inline void Initialize(uint16 opcode ) 97 { 98 StackBuffer
::Clear(); 99 m_opcode = opcode;100 }101 102 uint16 GetOpcode() { return m_opcode; }103 __inline void SetOpcode(uint16 opcode) { m_opcode = opcode; }104 };105 */106 107 #endif

Common.h (bytebuffer.h所需的一些定义,该文件来自“魔兽世界服务端”源码,cocos2d-x自身有个CCommon.h文件,如果把两个文件合并的话,在linux下编译会发生冲突,冲突较多,本人也没有做区分,因此建议独立出来)

1 #ifndef WGSERVER_COMMON_H  2 #define WGSERVER_COMMON_H  3   4   5 #ifdef WIN32  6 #pragma warning(disable:4996)  7 #define _CRT_SECURE_NO_DEPRECATE 1  8 #define _CRT_SECURE_COPP_OVERLOAD_STANDARD_NAMES 1  9 #pragma warning(disable:4251)        // dll-interface bullshit 10 #endif 11  12 enum TimeVariables 13 { 14     TIME_SECOND = 1, 15     TIME_MINUTE = TIME_SECOND * 60, 16     TIME_HOUR   = TIME_MINUTE * 60, 17     TIME_DAY    = TIME_HOUR * 24, 18     TIME_MONTH    = TIME_DAY * 30, 19     TIME_YEAR    = TIME_MONTH * 12 20 }; 21  22 enum MsTimeVariables 23 { 24     MSTIME_SECOND = 1000, 25     MSTIME_MINUTE = MSTIME_SECOND * 60, 26     MSTIME_HOUR   = MSTIME_MINUTE * 60, 27     MSTIME_DAY      = MSTIME_HOUR * 24 28 }; 29  30 #ifdef WIN32 31 #define WGSERVER_INLINE __forceinline 32 #else 33 #define WGSERVER_INLINE inline 34 #endif 35  36 #ifdef HAVE_CONFIG_H 37 # include 
38 #endif 39 40 41 /* Define this if you're using a big-endian machine */ 42 #ifdef USING_BIG_ENDIAN 43 #include
44 #define bswap_16(x) NXSwapShort(x) 45 #define bswap_32(x) NXSwapInt(x) 46 #define bswap_64(x) NXSwapLongLong(x) 47 #endif 48 49 #include
50 #include
51 #include
52 #include
53 #include
54 #include
55 #include
56 //#include
57 58 59 #if defined( __WIN32__ ) || defined( WIN32 ) || defined( _WIN32 ) 60 # define WIN32_LEAN_AND_MEAN 61 //# define _WIN32_WINNT 0x0500 62 # define NOMINMAX 63 # include
64 #else 65 # include
66 # define MAX_PATH 1024 67 #endif 68 69 #ifdef min 70 #undef min 71 #endif 72 73 #ifdef max 74 #undef max 75 #endif 76 77 #ifdef CONFIG_USE_SELECT 78 #undef FD_SETSIZE 79 #define FD_SETSIZE 2048 80 #endif 81 82 #if defined( __WIN32__ ) || defined( WIN32 ) || defined( _WIN32 ) 83 #include
84 #include
85 #else 86 #include
87 #include
88 #include
89 #include
90 #include
91 #include
92 #include
93 #include
94 #include
95 #endif 96 97 // current platform and compiler 98 #define PLATFORM_WIN32 0 99 #define PLATFORM_UNIX 1100 #define PLATFORM_APPLE 2101 102 #define UNIX_FLAVOUR_LINUX 1103 #define UNIX_FLAVOUR_BSD 2104 #define UNIX_FLAVOUR_OTHER 3105 #define UNIX_FLAVOUR_OSX 4106 107 #if defined( __WIN32__ ) || defined( WIN32 ) || defined( _WIN32 )108 # define PLATFORM PLATFORM_WIN32109 #elif defined( __APPLE_CC__ )110 # define PLATFORM PLATFORM_APPLE111 #else112 # define PLATFORM PLATFORM_UNIX113 #endif114 115 #define COMPILER_MICROSOFT 0116 #define COMPILER_GNU 1117 #define COMPILER_BORLAND 2118 119 #ifdef _MSC_VER120 # define COMPILER COMPILER_MICROSOFT121 #elif defined( __BORLANDC__ )122 # define COMPILER COMPILER_BORLAND123 #elif defined( __GNUC__ )124 # define COMPILER COMPILER_GNU125 #else126 # pragma error "FATAL ERROR: Unknown compiler."127 #endif128 129 #if PLATFORM == PLATFORM_UNIX || PLATFORM == PLATFORM_APPLE130 #ifdef HAVE_DARWIN131 #define PLATFORM_TEXT "MacOSX"132 #define UNIX_FLAVOUR UNIX_FLAVOUR_OSX133 #else134 #ifdef USE_KQUEUE135 #define PLATFORM_TEXT "FreeBSD"136 #define UNIX_FLAVOUR UNIX_FLAVOUR_BSD137 #else138 #define PLATFORM_TEXT "Linux"139 #define UNIX_FLAVOUR UNIX_FLAVOUR_LINUX140 #endif141 #endif142 #endif143 144 #if PLATFORM == PLATFORM_WIN32145 #define PLATFORM_TEXT "Win32"146 #endif147 148 #ifdef _DEBUG149 #define CONFIG "Debug"150 #else151 #define CONFIG "Release"152 #endif153 154 #ifdef USING_BIG_ENDIAN155 #define ARCH "PPC"156 #else157 #ifdef X64158 #define ARCH "X64"159 #else160 #define ARCH "X86"161 #endif162 #endif163 164 /*#if COMPILER == COMPILER_MICROSOFT165 # pragma warning( disable : 4267 ) // conversion from 'size_t' to 'int', possible loss of data166 # pragma warning( disable : 4311 ) // 'type cast': pointer truncation from HMODULE to uint32167 # pragma warning( disable : 4786 ) // identifier was truncated to '255' characters in the debug information168 # pragma warning( disable : 4146 )169 # pragma warning( disable : 4800 )170 #endif*/171 172 #if PLATFORM == PLATFORM_WIN32173 #define STRCASECMP stricmp174 #else175 #define STRCASECMP strcasecmp176 #endif177 178 #if PLATFORM == PLATFORM_WIN32179 #define ASYNC_NET180 #endif181 182 #ifdef USE_EPOLL183 #define CONFIG_USE_EPOLL184 #endif185 #ifdef USE_KQUEUE186 #define CONFIG_USE_KQUEUE187 #endif188 #ifdef USE_SELECT189 #define CONFIG_USE_SELECT190 #endif191 #ifdef USE_POLL192 #define CONFIG_USE_POLL193 #endif194 195 #ifdef min196 #undef min197 #endif198 199 #ifdef max200 #undef max201 #endif202 203 #include
204 #include
205 #include
206 #include
207 #include
208 #include
209 #include
210 #include
211 #include
212 #include
213 #include
214 //#include
215 216 #if defined ( __GNUC__ )217 # define LIKELY( _x ) \218 __builtin_expect( ( _x ), 1 )219 # define UNLIKELY( _x ) \220 __builtin_expect( ( _x ), 0 )221 #else222 # define LIKELY( _x ) \223 _x224 # define UNLIKELY( _x ) \225 _x226 #endif227 228 #if defined (__GNUC__)229 # define GCC_VERSION (__GNUC__ * 10000 \230 + __GNUC_MINOR__ * 100 \231 + __GNUC_PATCHLEVEL__)232 #endif233 234 235 #ifndef WIN32236 #ifndef X64237 # if defined (__GNUC__)238 # if GCC_VERSION >= 30400239 # ifdef HAVE_DARWIN240 # define __fastcall241 # else242 # define __fastcall __attribute__((__fastcall__))243 # endif244 # else245 # define __fastcall __attribute__((__regparm__(3)))246 # endif247 # else248 # define __fastcall __attribute__((__fastcall__))249 # endif250 #else251 #define __fastcall 252 #endif253 #endif254 255 #ifdef HAVE_STDCXX_0X256 #include
257 #include
258 #elif COMPILER == COMPILER_GNU && __GNUC__ >= 3259 #include
260 #include
261 #else262 #include
263 #include
264 #endif265 266 267 268 #ifdef _STLPORT_VERSION269 #define HM_NAMESPACE std270 using std::hash_map;271 using std::hash_set;272 #elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1300273 #define HM_NAMESPACE stdext274 using stdext::hash_map;275 using stdext::hash_set;276 #define ENABLE_SHITTY_STL_HACKS 1277 278 /*279 # if GNUC_COMP_VER >= 430280 # define HashMap ::std::tr1::unordered_map281 # define HashSet ::std::tr1::unordered_set282 # else283 # define HashMap ::__gnu_cxx::hash_map284 # define HashSet ::__gnu_cxx::hash_set285 # endif286 */287 288 #define HashMap ::__gnu_cxx::hash_map289 #define HashSet ::__gnu_cxx::hash_set290 291 292 // hacky stuff for vc++293 #define snprintf _snprintf294 #define vsnprintf _vsnprintf295 //#define strlen lstrlen296 297 #ifdef WIN32298 //typedef char TCHAR;299 #define __T(x) x300 #endif301 302 // cebernic added it303 #define __utf8(x) _StringToUTF8(x)304 #define __ansi(x) _StringToANSI(x)305 #define __isutf8(x) _IsStringUTF8(x)306 307 308 #elif COMPILER == COMPILER_INTEL309 #define HM_NAMESPACE std310 using std::hash_map;311 using std::hash_set;312 #elif defined(HAVE_STDCXX_0X)313 #define HM_NAMESPACE std314 #define hash_map unordered_map315 #define hash_set unordered_set316 using std::unordered_map;317 using std::unordered_set;318 #elif COMPILER == COMPILER_GNU && __GNUC__ >= 3319 #define HM_NAMESPACE __gnu_cxx320 using __gnu_cxx::hash_map;321 using __gnu_cxx::hash_set;322 323 namespace __gnu_cxx324 {325 template<> struct hash
326 {327 size_t operator()(const unsigned long long &__x) const { return (size_t)__x; }328 };329 template
struct hash
330 {331 size_t operator()(T * const &__x) const { return (size_t)__x; }332 };333 334 };335 336 #else337 #define HM_NAMESPACE std338 using std::hash_map;339 #endif340 341 /* Use correct types for x64 platforms, too */342 #if COMPILER != COMPILER_GNU343 typedef signed __int64 int64;344 typedef signed __int32 int32;345 typedef signed __int16 int16;346 typedef signed __int8 int8;347 348 typedef unsigned __int64 uint64;349 typedef unsigned __int32 uint32;350 typedef unsigned __int16 uint16;351 typedef unsigned __int8 uint8;352 typedef float Real;353 #else354 355 typedef int64_t int64;356 typedef int32_t int32;357 typedef int16_t int16;358 typedef int8_t int8;359 typedef uint64_t uint64;360 typedef uint32_t uint32;361 typedef uint16_t uint16;362 typedef uint8_t uint8;363 typedef uint32_t DWORD;364 typedef float Real;365 366 #endif367 368 /* these can be optimized into assembly */369 #ifdef USING_BIG_ENDIAN370 371 WGSERVER_INLINE static void swap16(uint16* p) { *p = bswap_16((uint16_t)*p); }372 WGSERVER_INLINE static void swap32(uint32* p) { *p = bswap_32((uint32_t)*p); }373 WGSERVER_INLINE static void swap64(uint64* p) { *p = bswap_64((uint64_t)*p);; }374 375 WGSERVER_INLINE static float swapfloat(float p)376 {377 union { float asfloat; uint8 asbytes[4]; } u1, u2;378 u1.asfloat = p;379 /* swap! */380 u2.asbytes[0] = u1.asbytes[3];381 u2.asbytes[1] = u1.asbytes[2];382 u2.asbytes[2] = u1.asbytes[1];383 u2.asbytes[3] = u1.asbytes[0];384 385 return u2.asfloat;386 }387 388 WGSERVER_INLINE static double swapdouble(double p)389 {390 union { double asfloat; uint8 asbytes[8]; } u1, u2;391 u1.asfloat = p;392 /* swap! */393 u2.asbytes[0] = u1.asbytes[7];394 u2.asbytes[1] = u1.asbytes[6];395 u2.asbytes[2] = u1.asbytes[5];396 u2.asbytes[3] = u1.asbytes[4];397 u2.asbytes[4] = u1.asbytes[3];398 u2.asbytes[5] = u1.asbytes[2];399 u2.asbytes[6] = u1.asbytes[1];400 u2.asbytes[7] = u1.asbytes[0];401 402 return u2.asfloat;403 }404 405 WGSERVER_INLINE static void swapfloat(float * p)406 {407 union { float asfloat; uint8 asbytes[4]; } u1, u2;408 u1.asfloat = *p;409 /* swap! */410 u2.asbytes[0] = u1.asbytes[3];411 u2.asbytes[1] = u1.asbytes[2];412 u2.asbytes[2] = u1.asbytes[1];413 u2.asbytes[3] = u1.asbytes[0];414 *p = u2.asfloat;415 }416 417 WGSERVER_INLINE static void swapdouble(double * p)418 {419 union { double asfloat; uint8 asbytes[8]; } u1, u2;420 u1.asfloat = *p;421 /* swap! */422 u2.asbytes[0] = u1.asbytes[7];423 u2.asbytes[1] = u1.asbytes[6];424 u2.asbytes[2] = u1.asbytes[5];425 u2.asbytes[3] = u1.asbytes[4];426 u2.asbytes[4] = u1.asbytes[3];427 u2.asbytes[5] = u1.asbytes[2];428 u2.asbytes[6] = u1.asbytes[1];429 u2.asbytes[7] = u1.asbytes[0];430 *p = u2.asfloat;431 }432 433 WGSERVER_INLINE static uint16 swap16(uint16 p) { return bswap_16((uint16_t)p); }434 WGSERVER_INLINE static uint32 swap32(uint32 p) { return bswap_32((uint32_t)p); }435 WGSERVER_INLINE static uint64 swap64(uint64 p) { return bswap_64((uint64_t)p); }436 437 WGSERVER_INLINE static void swap16(int16* p) { *p = bswap_16((uint16_t)*p); }438 WGSERVER_INLINE static void swap32(int32* p) { *p = bswap_32((uint32_t)*p); }439 WGSERVER_INLINE static void swap64(int64* p) { *p = bswap_64((uint64_t)*p); }440 441 WGSERVER_INLINE static int16 swap16(int16 p) { return bswap_16((uint16_t)p); }442 WGSERVER_INLINE static int32 swap32(int32 p) { return bswap_32((uint32_t)p); }443 WGSERVER_INLINE static int64 swap64(int64 p) { return bswap_64((uint64_t)p); }444 445 #endif446 /* 447 Scripting system exports/imports448 */449 450 #ifdef WIN32451 #ifndef SCRIPTLIB452 #define SERVER_DECL __declspec(dllexport)453 #define SCRIPT_DECL __declspec(dllimport)454 #else455 #define SERVER_DECL __declspec(dllimport)456 #define SCRIPT_DECL __declspec(dllexport)457 #endif458 #else459 #define SERVER_DECL 460 #define SCRIPT_DECL 461 #endif462 463 // Include all threading files464 #include
465 //#include "Threading/Threading.h"466 467 //#include "MersenneTwister.h"468 469 #if COMPILER == COMPILER_MICROSOFT470 471 #define I64FMT "%016I64X"472 #define I64FMTD "%I64u"473 #define SI64FMTD "%I64d"474 #define snprintf _snprintf475 #define atoll __atoi64476 477 #else478 479 #define stricmp strcasecmp480 #define strnicmp strncasecmp481 #define I64FMT "%016llX"482 #define I64FMTD "%llu"483 #define SI64FMTD "%lld"484 485 #endif486 487 #ifndef WIN32488 #ifdef USING_BIG_ENDIAN489 //#define GUID_HIPART(x) (*((uint32*)&(x)))490 //#define GUID_LOPART(x) (*(((uint32*)&(x))+1))491 #define GUID_LOPART(x) ( ( x >> 32 ) )492 #define GUID_HIPART(x) ( ( x & 0x00000000ffffffff ) )493 #else494 #define GUID_HIPART(x) ( ( x >> 32 ) )495 #define GUID_LOPART(x) ( ( x & 0x00000000ffffffff ) )496 #endif497 #else498 #define GUID_HIPART(x) (*(((uint32*)&(x))+1))499 #define GUID_LOPART(x) (*((uint32*)&(x)))500 #endif501 502 #define atol(a) strtoul( a, NULL, 10)503 504 #define STRINGIZE(a) #a505 506 // fix buggy MSVC's for variable scoping to be reliable =S507 #define for if(true) for508 509 #if COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1400510 #pragma float_control(push)511 #pragma float_control(precise, on)512 #endif513 514 // fast int abs515 static inline int int32abs( const int value )516 {517 return (value ^ (value >> 31)) - (value >> 31);518 }519 520 // fast int abs and recast to unsigned521 static inline uint32 int32abs2uint32( const int value )522 {523 return (uint32)(value ^ (value >> 31)) - (value >> 31);524 }525 526 /// Fastest Method of float2int32527 static inline int float2int32(const float value)528 {529 #if !defined(X64) && COMPILER == COMPILER_MICROSOFT && !defined(USING_BIG_ENDIAN)530 int i;531 __asm {532 fld value533 frndint534 fistp i535 }536 return i;537 #else538 union { int asInt[2]; double asDouble; } n;539 n.asDouble = value + 6755399441055744.0;540 541 #if USING_BIG_ENDIAN542 return n.asInt [1];543 #else544 return n.asInt [0];545 #endif546 #endif547 }548 549 /// Fastest Method of long2int32550 static inline int long2int32(const double value)551 {552 #if !defined(X64) && COMPILER == COMPILER_MICROSOFT && !defined(USING_BIG_ENDIAN)553 int i;554 __asm {555 fld value556 frndint557 fistp i558 }559 return i;560 #else561 union { int asInt[2]; double asDouble; } n;562 n.asDouble = value + 6755399441055744.0;563 564 #if USING_BIG_ENDIAN565 return n.asInt [1];566 #else567 return n.asInt [0];568 #endif569 #endif570 }571 572 #if COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1400573 #pragma float_control(pop)574 #endif575 576 #ifndef WIN32577 #include
578 #endif579 580 581 extern uint32 system_start_time_t;582 583 WGSERVER_INLINE uint32 now()584 { 585 #ifdef WIN32586 return GetTickCount();587 #else588 struct timeval tv;589 gettimeofday(&tv, NULL);590 return ((tv.tv_sec - system_start_time_t) * 1000) + (tv.tv_usec / 1000);591 #endif592 }593 594 #ifndef WIN32595 #define FALSE 0596 #define TRUE 1597 #endif598 599 #ifndef WIN32600 #define Sleep(ms) usleep(1000*ms)601 #endif602 603 /*#ifdef WIN32604 #ifndef __SHOW_STUPID_WARNINGS__605 #pragma warning(disable:4018)606 #pragma warning(disable:4244)607 #pragma warning(disable:4305) 608 #pragma warning(disable:4748)609 #pragma warning(disable:4800) 610 #pragma warning(disable:4996)611 #pragma warning(disable:4251)612 #endif 613 #endif614 615 #undef INTEL_COMPILER616 #ifdef INTEL_COMPILER617 #pragma warning(disable:279)618 #pragma warning(disable:1744)619 #pragma warning(disable:1740)620 #endif*/621 622 //#include "Util.h"623 struct WayPoint624 {625 WayPoint()626 {627 o = 0.0f;628 }629 uint32 id;630 float x;631 float y;632 float z;633 float o;634 uint32 waittime; //ms635 uint32 flags;636 bool forwardemoteoneshot;637 uint32 forwardemoteid;638 bool backwardemoteoneshot;639 uint32 backwardemoteid;640 uint32 forwardskinid;641 uint32 backwardskinid;642 643 };644 645 struct spawn_timed_emotes646 {647 uint8 type; //1 standstate, 2 emotestate, 3 emoteoneshot648 uint32 value; //get yar list elsewhere649 char *msg; //maybe we wish to say smething while changing emote state650 uint8 msg_type; //yell ? say ?651 uint8 msg_lang; //yell ? say ?652 uint32 expire_after; //going to nex faze in653 };654 typedef std::list
TimedEmoteList;655 656 WGSERVER_INLINE void reverse_array(uint8 * pointer, size_t count)657 {658 size_t x;659 uint8 * temp = (uint8*)malloc(count);660 memcpy(temp, pointer, count);661 for(x = 0; x < count; ++x)662 pointer[x] = temp[count-x-1];663 free(temp);664 }665 666 typedef std::vector
WayPointMap;667 668 int32 GetTimePeriodFromString(const char * str);669 std::string ConvertTimeStampToString(uint32 timestamp);670 std::string ConvertTimeStampToDataTime(uint32 timestamp);671 672 uint32 DecimalToMask(uint32 dec);673 674 WGSERVER_INLINE void wgs_TOLOWER(std::string& str)675 {676 for(size_t i = 0; i < str.length(); ++i)677 str[i] = (char)tolower(str[i]);678 }679 680 WGSERVER_INLINE void wgs_TOUPPER(std::string& str)681 {682 for(size_t i = 0; i < str.length(); ++i)683 str[i] = (char)toupper(str[i]);684 }685 686 // returns true if the ip hits the mask, otherwise false687 inline static bool ParseCIDRBan(unsigned int IP, unsigned int Mask, unsigned int MaskBits)688 {689 // CIDR bans are a compacted form of IP / Submask690 // So 192.168.1.0/255.255.255.0 would be 192.168.1.0/24691 // IP's in the 192.168l.1.x range would be hit, others not.692 unsigned char * source_ip = (unsigned char*)&IP;693 unsigned char * mask = (unsigned char*)&Mask;694 int full_bytes = MaskBits / 8;695 int leftover_bits = MaskBits % 8;696 //int byte;697 698 // sanity checks for the data first699 if( MaskBits > 32 )700 return false;701 702 // this is the table for comparing leftover bits703 static const unsigned char leftover_bits_compare[9] = {704 0x00, // 00000000705 0x80, // 10000000706 0xC0, // 11000000707 0xE0, // 11100000708 0xF0, // 11110000709 0xF8, // 11111000710 0xFC, // 11111100711 0xFE, // 11111110712 0xFF, // 11111111 - This one isn't used713 };714 715 // if we have any full bytes, compare them with memcpy716 if( full_bytes > 0 )717 {718 if( memcmp( source_ip, mask, full_bytes ) != 0 )719 return false;720 }721 722 // compare the left over bits723 if( leftover_bits > 0 )724 {725 if( ( source_ip[full_bytes] & leftover_bits_compare[leftover_bits] ) !=726 ( mask[full_bytes] & leftover_bits_compare[leftover_bits] ) )727 {728 // one of the bits does not match729 return false;730 }731 }732 733 // all of the bits match that were testable734 return true;735 }736 737 inline static unsigned int MakeIP(const char * str)738 {739 unsigned int bytes[4];740 unsigned int res;741 if( sscanf(str, "%u.%u.%u.%u", &bytes[0], &bytes[1], &bytes[2], &bytes[3]) != 4 )742 return 0;743 744 res = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);745 return res;746 }747 748 749 inline static unsigned int GetANetwork(unsigned int ip)750 {751 return (ip & 0x000000FF);752 }753 754 inline static unsigned int GetBNetwork(unsigned int ip)755 {756 return (ip & 0x0000FFFF);757 }758 759 inline static unsigned int GetCNetwork(unsigned int ip)760 {761 return (ip & 0x00FFFFFF);762 }763 764 765 //get current thread id766 #define getThreadId() syscall(__NR_gettid)767 768 // warning, by enabling this define you are aware that you are only delaying the inevitable769 // some crashes are not recorable and those will stack up in time and lead to a full crash770 // enabling this define will make windows servers shut down only the map instance in where the crash ocured771 // during this forced shutdown players are not saved to avoid saving corrupted data772 // there might be a lot of cases where each saved crash will lead to memory leaks or unhandled cases773 // crashreports are still created and do use them to report the actaul problem that casued the crash774 // fixing the problem that causes the crash is the proper way to fix things775 //#define FORCED_SERVER_KEEPALIVE776 777 778 #endif

另外,

在extensions/cocos-ext.h文件内加入

#include "network/TCPSocket.h"

在extensions/Android.mk文件内加入,使其在linux下能够编译到

network/TCPSocket.cpp \

使用例子,代码片段:

///    // 创建SOCKET管理器    CREATE_TCPSOCKETMGR(this);        // 创建并添加SOCKET,参数:服务器IP,端口,自定义的SOCKET_ID标识    sSocketMgr.createSocket("192.168.0.183", 7502, 1);    // 注册协议,参数:包头,回调函数    sSocketMgr.register_process(0x10, SCT_CALLBACK_2(HelloWorld::login, this));    // 注册消息截获事件,注册此事件后可以截获收到的所有消息,若回调函数返回true则本次事件会继续分发注册过的协议,返回false则不分发    sSocketMgr.register_all_process(SCT_CALLBACK_1(HelloWorld::process, this));    // 定义协议包    WorldPacket packet;    packet.clear();    // 设置协议头    packet.SetOpcode(0x0010);    packet    << uint16(0x0010)             << uint16(0)// 协议长度            << uint32(1)             << uint32(0);    // 加入字符串数据(uint8表示字符串长度所占字节,此处为1字节)    packet.AppendPacketString
(std::string("aaa:88889083:d5956683c17d7e284d33ee295b277b52")); // 设置协议长度 packet.SetLength(packet.size()); // 发送数据 sSocketMgr.SendPacket(1, &packet); ///

回调函数例子:

1 // 注册单个协议回调函数(样例),参数:SOCKET_ID标识,数据包2     void process_login(int _tag, WorldPacket & packet);3     // 注册单个协议回调函数(样例),参数:SOCKET_ID标识,协议头,数据包4     bool process_all(int _tag, int _cmd, WorldPacket & packet);5     // 断线事件6     void onDisconnect(int _tag);

取数据例子:

WorldPacket packet ; // 取整形数据uint16 opcode;uint16 len;uint32 serial;float fl; packet >> opcode;packet >> len;packet >> serial;packet >> fl; // 取字符串String oldPwd, newPwd;    packet.GetPacketString
(&packet, oldPwd);packet.GetPacketString
(&packet, newPwd);

写得比较草,如果看不懂的,好的建议和意见可以给我留言。

如果有不同的,好的思路也可以提出来,一起探讨。。

转载于:https://www.cnblogs.com/elephant-x/p/3304903.html

你可能感兴趣的文章
Linux系统配置文件(红帽)7
查看>>
关于jenkins邮件配置
查看>>
Centos6 系统启动过程
查看>>
3 docker容器
查看>>
zebra 安装失败
查看>>
网络协议设计的一点思考
查看>>
算法学习之路|数字黑洞
查看>>
LoadRunner参数下载本地
查看>>
Linux安装配置ftp服务器
查看>>
radmin注册密码
查看>>
枫叶防注入程序漏洞
查看>>
AAA基础知识
查看>>
LG Display携手宝岛眼镜 不闪式3D亲民的新尝试
查看>>
mac下idea的使用之svn篇--有图超详细
查看>>
LACP和STP
查看>>
Docker管理工具Web UI:DockerUI & Shipyard
查看>>
OSSEC 加固linux系统详细配置
查看>>
CCNA配置试验之四 OSPF协议的配置
查看>>
RSA算法加解密示例
查看>>
分享一个消息组件
查看>>