包含到cocos2d-x里的tcpsocket源码

来源:互联网 发布:ubuntu卸载xampp 编辑:程序博客网 时间:2024/06/05 05:34

转自:http://www.cnblogs.com/elephant-x/archive/2013/09/06/3304903.html

声明:本文参考了langresser发布的blog“跨平台的游戏客户端Socket封装 

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

本文基于cocos2d-x3.0+VS2012

点击下载:network.zip

文件目录结构截图:

 

文件源码:

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 <windows.h>  9 #include <WinSock.h> 10 #pragma comment( lib, "ws2_32.lib" ) 11 #else 12 #include <sys/socket.h> 13 #include <fcntl.h> 14 #include <errno.h> 15 #include <netinet/in.h> 16 #include <arpa/inet.h> 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<bool(int,int,WorldPacket&)> ProAllFunc;    // 接收所有协议,自行处理,@socket标识,@协议头,@数据包,返回是否分发 73 typedef std::function<void(int,WorldPacket&)> ProFunc;    // 接收单个协议,@socket标识,@数据包 74 typedef std::function<void(int)> 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<TCPSocket*> m_lstSocket;129     std::map<uint16, ProFunc> _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<TCPSocket*>::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<TCPSocket*>::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<TCPSocket*>::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<TCPSocket*>::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<uint16, ProFunc>::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<TCPSocket*>::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<TCPSocket*>::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<typename T> 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<typename T>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<type>(); }172 #define DEFINE_BUFFER_WRITE_OPERATOR(type) void operator << (const type src) { Write<type>(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<char>() > 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<char>();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<typename T> size_t writeVector(std::vector<T> &v)237     {238             for (typename std::vector<T>::const_iterator i = v.begin(); i != v.end(); i++) {239                     Write<T>(*i);240             }241             return v.size();242         243     }244     template<typename T> size_t readVector(size_t vsize, std::vector<T> &v)245     {246         247         v.clear();248         while(vsize--) {249             T t = Read<T>();250             v.push_back(t);251         }252         return v.size();253     }254 255     template<typename T> size_t writeList(std::list<T> &v)256     {257             for (typename std::list<T>::const_iterator i = v.begin(); i != v.end(); i++) {258                     Write<T>(*i);259             }260             return v.size();261         262     }263     template<typename T> size_t readList(size_t vsize, std::list<T> &v)264     {265         266         v.clear();267         while(vsize--) {268             T t = Read<T>();269             v.push_back(t);270         }271         return v.size();272     }273 274     template <typename K, typename V> size_t writeMap(const std::map<K, V> &m)275     {276         for (typename std::map<K, V>::const_iterator i = m.begin(); i != m.end(); i++) {277             Write<K>(i->first);278             Write<V>(i->second);279         }280         return m.size();281     }282 283     template <typename K, typename V> size_t readMap(size_t msize, std::map<K, V> &m)284     {285         m.clear();286         while(msize--) {287             K k = Read<K>();288             V v = Read<V>();289             m.insert(make_pair(k, v));290         }291         return m.size();292     }293 294 };295 296 ///////////////////////////////////////////////////////////////////////////////297 ///////////////////////////////////////////////////////////////////////////////298 ///////////////////////////////////////////////////////////////////////////////299 300 template <typename T> ByteBuffer &operator<<(ByteBuffer &b, const std::vector<T> & v)301 {302     b << (uint32)v.size();303     for (typename std::vector<T>::const_iterator i = v.begin(); i != v.end(); i++) {304         b << *i;305     }306     return b;307 }308 309 template <typename T> ByteBuffer &operator>>(ByteBuffer &b, std::vector<T> &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 <typename T> ByteBuffer &operator<<(ByteBuffer &b, const std::list<T> & v)323 {324     b << (uint32)v.size();325     for (typename std::list<T>::const_iterator i = v.begin(); i != v.end(); i++) {326         b << *i;327     }328     return b;329 }330 331 template <typename T> ByteBuffer &operator>>(ByteBuffer &b, std::list<T> &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 <typename K, typename V> ByteBuffer &operator<<(ByteBuffer &b, const std::map<K, V> &m)345 {346     b << (uint32)m.size();347     for (typename std::map<K, V>::const_iterator i = m.begin(); i != m.end(); i++) {348         b << i->first << i->second;349     }350     return b;351 }352 353 template <typename K, typename V> ByteBuffer &operator>>(ByteBuffer &b, std::map<K, V> &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<typename T> 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<typename T> 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<typename T> 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<uint32 Size> 89 class SERVER_DECL StackWorldPacket : public StackBuffer<Size> 90 { 91     uint16 m_opcode; 92 public: 93     __inline StackWorldPacket(uint16 opcode) : StackBuffer<Size>(), m_opcode(opcode) { } 94  95     //! Clear packet and set opcode all in one mighty blow 96     __inline void Initialize(uint16 opcode ) 97     { 98         StackBuffer<Size>::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 <config.h> 38 #endif 39  40  41 /* Define this if you're using a big-endian machine */ 42 #ifdef USING_BIG_ENDIAN 43 #include <machine/byte_order.h> 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 <cstdlib> 50 #include <stdio.h> 51 #include <stdlib.h> 52 #include <stdarg.h> 53 #include <time.h> 54 #include <math.h> 55 #include <errno.h> 56 //#include <sys/syscall.h> 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 <windows.h> 64 #else 65 #  include <string.h> 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 <winsock2.h> 84 #include <ws2tcpip.h> 85 #else 86 #include <sys/time.h> 87 #include <sys/types.h> 88 #include <sys/ioctl.h> 89 #include <sys/socket.h> 90 #include <netinet/in.h> 91 #include <arpa/inet.h> 92 #include <unistd.h> 93 #include <signal.h> 94 #include <netdb.h> 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 <cstdlib>204 #include <set>205 #include <list>206 #include <string>207 #include <map>208 #include <queue>209 #include <sstream>210 #include <algorithm>211 #include <cstring>212 #include <climits>213 #include <cstdlib>214 //#include <iostream>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 <unordered_map>257 #include <unordered_set>258 #elif COMPILER == COMPILER_GNU && __GNUC__ >= 3259 #include <ext/hash_map>260 #include <ext/hash_set>261 #else262 #include <hash_map>263 #include <hash_set>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<unsigned long long>326     {327         size_t operator()(const unsigned long long &__x) const { return (size_t)__x; }328     };329     template<typename T> struct hash<T *>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 <assert.h>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 <sys/timeb.h>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<spawn_timed_emotes*> 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<WayPoint*> 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<uint8>(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<uint8>(&packet, oldPwd);packet.GetPacketString<uint8>(&packet, newPwd);
复制代码

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

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

分类: Android, cocos2d-x, socket
0 0
原创粉丝点击