包含到cocos2d-x里的tcpsocket源码

声明:本文参考了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     // 删除socket
112     bool    removeSocket(int _tag);
113     // 断开socket
114     void    disconnect(int _tag);
115     // 获取socket
116     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_END
135 
136 #endif //__CC_TCPSOCKET_H__

TCPSocket.cpp

#include "TCPSocket.h"
#include "support/zip_support/unzip.h"


NS_CC_EXT_BEGIN
TCPSocket::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;
}

// 删除socket
bool    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 buffer
111      */
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 written
123      */
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 overflows
139      * @param ptr the data to be written
140      * @param size byte count
141     */
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 fit
157      */
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 operators
180     */
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 operators
204      */
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) operators
209      */
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 position
225      * @return buffer size
226      */
227     inline size_t size() { return m_writePos; }
228 
229     /** read/write position setting/getting
230      */
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  1
100 #define PLATFORM_APPLE 2
101 
102 #define UNIX_FLAVOUR_LINUX 1
103 #define UNIX_FLAVOUR_BSD 2
104 #define UNIX_FLAVOUR_OTHER 3
105 #define UNIX_FLAVOUR_OSX 4
106 
107 #if defined( __WIN32__ ) || defined( WIN32 ) || defined( _WIN32 )
108 #  define PLATFORM PLATFORM_WIN32
109 #elif defined( __APPLE_CC__ )
110 #  define PLATFORM PLATFORM_APPLE
111 #else
112 #  define PLATFORM PLATFORM_UNIX
113 #endif
114 
115 #define COMPILER_MICROSOFT 0
116 #define COMPILER_GNU       1
117 #define COMPILER_BORLAND   2
118 
119 #ifdef _MSC_VER
120 #  define COMPILER COMPILER_MICROSOFT
121 #elif defined( __BORLANDC__ )
122 #  define COMPILER COMPILER_BORLAND
123 #elif defined( __GNUC__ )
124 #  define COMPILER COMPILER_GNU
125 #else
126 #  pragma error "FATAL ERROR: Unknown compiler."
127 #endif
128 
129 #if PLATFORM == PLATFORM_UNIX || PLATFORM == PLATFORM_APPLE
130 #ifdef HAVE_DARWIN
131 #define PLATFORM_TEXT "MacOSX"
132 #define UNIX_FLAVOUR UNIX_FLAVOUR_OSX
133 #else
134 #ifdef USE_KQUEUE
135 #define PLATFORM_TEXT "FreeBSD"
136 #define UNIX_FLAVOUR UNIX_FLAVOUR_BSD
137 #else
138 #define PLATFORM_TEXT "Linux"
139 #define UNIX_FLAVOUR UNIX_FLAVOUR_LINUX
140 #endif
141 #endif
142 #endif
143 
144 #if PLATFORM == PLATFORM_WIN32
145 #define PLATFORM_TEXT "Win32"
146 #endif
147 
148 #ifdef _DEBUG
149 #define CONFIG "Debug"
150 #else
151 #define CONFIG "Release"
152 #endif
153 
154 #ifdef USING_BIG_ENDIAN
155 #define ARCH "PPC"
156 #else
157 #ifdef X64
158 #define ARCH "X64"
159 #else
160 #define ARCH "X86"
161 #endif
162 #endif
163 
164 /*#if COMPILER == COMPILER_MICROSOFT
165 #  pragma warning( disable : 4267 ) // conversion from 'size_t' to 'int', possible loss of data
166 #  pragma warning( disable : 4311 ) // 'type cast': pointer truncation from HMODULE to uint32
167 #  pragma warning( disable : 4786 ) // identifier was truncated to '255' characters in the debug information
168 #  pragma warning( disable : 4146 )
169 #  pragma warning( disable : 4800 )
170 #endif*/
171 
172 #if PLATFORM == PLATFORM_WIN32
173 #define STRCASECMP stricmp
174 #else
175 #define STRCASECMP strcasecmp
176 #endif
177 
178 #if PLATFORM == PLATFORM_WIN32
179     #define ASYNC_NET
180 #endif
181 
182 #ifdef USE_EPOLL
183     #define CONFIG_USE_EPOLL
184 #endif
185 #ifdef USE_KQUEUE
186     #define CONFIG_USE_KQUEUE
187 #endif
188 #ifdef USE_SELECT
189     #define CONFIG_USE_SELECT
190 #endif
191 #ifdef USE_POLL
192     #define CONFIG_USE_POLL
193 #endif
194 
195 #ifdef min
196 #undef min
197 #endif
198 
199 #ifdef max
200 #undef max
201 #endif
202 
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 #else
222 #    define LIKELY( _x ) \
223         _x
224 #    define UNLIKELY( _x ) \
225         _x
226 #endif
227 
228 #if defined (__GNUC__)
229 #  define GCC_VERSION (__GNUC__ * 10000 \
230                        + __GNUC_MINOR__ * 100 \
231                        + __GNUC_PATCHLEVEL__)
232 #endif
233 
234 
235 #ifndef WIN32
236 #ifndef X64
237 #  if defined (__GNUC__)
238 #    if GCC_VERSION >= 30400
239 #         ifdef HAVE_DARWIN
240 #          define __fastcall
241 #         else
242 #              define __fastcall __attribute__((__fastcall__))
243 #         endif
244 #    else
245 #      define __fastcall __attribute__((__regparm__(3)))
246 #    endif
247 #  else
248 #    define __fastcall __attribute__((__fastcall__))
249 #  endif
250 #else
251 #define __fastcall  
252 #endif
253 #endif
254 
255 #ifdef HAVE_STDCXX_0X
256 #include <unordered_map>
257 #include <unordered_set>
258 #elif COMPILER == COMPILER_GNU && __GNUC__ >= 3
259 #include <ext/hash_map>
260 #include <ext/hash_set>
261 #else
262 #include <hash_map>
263 #include <hash_set>
264 #endif
265 
266 
267 
268 #ifdef _STLPORT_VERSION
269 #define HM_NAMESPACE std
270 using std::hash_map;
271 using std::hash_set;
272 #elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1300
273 #define HM_NAMESPACE stdext
274 using stdext::hash_map;
275 using stdext::hash_set;
276 #define ENABLE_SHITTY_STL_HACKS 1
277 
278 /*
279         #   if GNUC_COMP_VER >= 430
280         #       define HashMap ::std::tr1::unordered_map
281         #               define HashSet ::std::tr1::unordered_set
282         #    else
283         #       define HashMap ::__gnu_cxx::hash_map
284         #       define HashSet ::__gnu_cxx::hash_set
285         #    endif
286 */
287 
288 #define HashMap ::__gnu_cxx::hash_map
289 #define HashSet ::__gnu_cxx::hash_set
290 
291 
292 // hacky stuff for vc++
293 #define snprintf _snprintf
294 #define vsnprintf _vsnprintf
295 //#define strlen lstrlen
296 
297 #ifdef WIN32
298 //typedef char TCHAR;
299 #define __T(x) x
300 #endif
301 
302 // cebernic added it
303 #define __utf8(x) _StringToUTF8(x)
304 #define __ansi(x) _StringToANSI(x)
305 #define __isutf8(x) _IsStringUTF8(x)
306 
307 
308 #elif COMPILER == COMPILER_INTEL
309 #define HM_NAMESPACE std
310 using std::hash_map;
311 using std::hash_set;
312 #elif defined(HAVE_STDCXX_0X)
313 #define HM_NAMESPACE std
314 #define hash_map unordered_map
315 #define hash_set unordered_set
316 using std::unordered_map;
317 using std::unordered_set;
318 #elif COMPILER == COMPILER_GNU && __GNUC__ >= 3
319 #define HM_NAMESPACE __gnu_cxx
320 using __gnu_cxx::hash_map;
321 using __gnu_cxx::hash_set;
322 
323 namespace __gnu_cxx
324 {
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 #else
337 #define HM_NAMESPACE std
338 using std::hash_map;
339 #endif
340 
341 /* Use correct types for x64 platforms, too */
342 #if COMPILER != COMPILER_GNU
343 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 #else
354 
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 #endif
367 
368 /* these can be optimized into assembly */
369 #ifdef USING_BIG_ENDIAN
370 
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 #endif
446 /* 
447 Scripting system exports/imports
448 */
449 
450 #ifdef WIN32
451     #ifndef SCRIPTLIB
452         #define SERVER_DECL __declspec(dllexport)
453         #define SCRIPT_DECL __declspec(dllimport)
454     #else
455         #define SERVER_DECL __declspec(dllimport)
456         #define SCRIPT_DECL __declspec(dllexport)
457     #endif
458 #else
459     #define SERVER_DECL 
460     #define SCRIPT_DECL 
461 #endif
462 
463 // Include all threading files
464 #include <assert.h>
465 //#include "Threading/Threading.h"
466 
467 //#include "MersenneTwister.h"
468 
469 #if COMPILER == COMPILER_MICROSOFT
470 
471 #define I64FMT "%016I64X"
472 #define I64FMTD "%I64u"
473 #define SI64FMTD "%I64d"
474 #define snprintf _snprintf
475 #define atoll __atoi64
476 
477 #else
478 
479 #define stricmp strcasecmp
480 #define strnicmp strncasecmp
481 #define I64FMT "%016llX"
482 #define I64FMTD "%llu"
483 #define SI64FMTD "%lld"
484 
485 #endif
486 
487 #ifndef WIN32
488 #ifdef USING_BIG_ENDIAN
489 //#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 #else
494 #define GUID_HIPART(x) ( ( x >> 32 ) )
495 #define GUID_LOPART(x) ( ( x & 0x00000000ffffffff ) )
496 #endif
497 #else
498 #define GUID_HIPART(x) (*(((uint32*)&(x))+1))
499 #define GUID_LOPART(x) (*((uint32*)&(x)))
500 #endif
501 
502 #define atol(a) strtoul( a, NULL, 10)
503 
504 #define STRINGIZE(a) #a
505 
506 // fix buggy MSVC's for variable scoping to be reliable =S
507 #define for if(true) for
508 
509 #if COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1400
510 #pragma float_control(push)
511 #pragma float_control(precise, on)
512 #endif
513 
514 // fast int abs
515 static inline int int32abs( const int value )
516 {
517     return (value ^ (value >> 31)) - (value >> 31);
518 }
519 
520 // fast int abs and recast to unsigned
521 static inline uint32 int32abs2uint32( const int value )
522 {
523     return (uint32)(value ^ (value >> 31)) - (value >> 31);
524 }
525 
526 /// Fastest Method of float2int32
527 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 value
533         frndint
534         fistp i
535     }
536     return i;
537 #else
538     union { int asInt[2]; double asDouble; } n;
539     n.asDouble = value + 6755399441055744.0;
540 
541 #if USING_BIG_ENDIAN
542     return n.asInt [1];
543 #else
544     return n.asInt [0];
545 #endif
546 #endif
547 }
548 
549 /// Fastest Method of long2int32
550 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 value
556         frndint
557         fistp i
558     }
559     return i;
560 #else
561   union { int asInt[2]; double asDouble; } n;
562   n.asDouble = value + 6755399441055744.0;
563 
564 #if USING_BIG_ENDIAN
565   return n.asInt [1];
566 #else
567   return n.asInt [0];
568 #endif
569 #endif
570 }
571 
572 #if COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1400
573 #pragma float_control(pop)
574 #endif
575 
576 #ifndef WIN32
577 #include <sys/timeb.h>
578 #endif
579 
580 
581 extern uint32 system_start_time_t;
582 
583 WGSERVER_INLINE uint32 now()
584 {    
585 #ifdef WIN32
586     return GetTickCount();
587 #else
588     struct timeval tv;
589     gettimeofday(&tv, NULL);
590     return ((tv.tv_sec - system_start_time_t) * 1000) + (tv.tv_usec / 1000);
591 #endif
592 }
593 
594 #ifndef WIN32
595 #define FALSE   0
596 #define TRUE    1
597 #endif
598 
599 #ifndef WIN32
600 #define Sleep(ms) usleep(1000*ms)
601 #endif
602 
603 /*#ifdef WIN32
604 #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 #endif
614 
615 #undef INTEL_COMPILER
616 #ifdef INTEL_COMPILER
617 #pragma warning(disable:279)
618 #pragma warning(disable:1744)
619 #pragma warning(disable:1740)
620 #endif*/
621 
622 //#include "Util.h"
623 struct WayPoint
624 {
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; //ms
635     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_emotes
646 {
647     uint8        type; //1 standstate, 2 emotestate, 3 emoteoneshot
648     uint32        value; //get yar list elsewhere
649     char        *msg; //maybe we wish to say smething while changing emote state
650     uint8        msg_type; //yell ? say ?
651     uint8        msg_lang; //yell ? say ?
652     uint32        expire_after; //going to nex faze in
653 };
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 false
687 inline static bool ParseCIDRBan(unsigned int IP, unsigned int Mask, unsigned int MaskBits)
688 {
689     // CIDR bans are a compacted form of IP / Submask
690     // So 192.168.1.0/255.255.255.0 would be 192.168.1.0/24
691     // 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 first
699     if( MaskBits > 32 )
700         return false;
701 
702     // this is the table for comparing leftover bits
703     static const unsigned char leftover_bits_compare[9] = {
704         0x00,            // 00000000
705         0x80,            // 10000000
706         0xC0,            // 11000000
707         0xE0,            // 11100000
708         0xF0,            // 11110000
709         0xF8,            // 11111000
710         0xFC,            // 11111100
711         0xFE,            // 11111110
712         0xFF,            // 11111111 - This one isn't used
713     };
714 
715     // if we have any full bytes, compare them with memcpy
716     if( full_bytes > 0 )
717     {
718         if( memcmp( source_ip, mask, full_bytes ) != 0 )
719             return false;
720     }
721 
722     // compare the left over bits
723     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 match
729             return false;
730         }
731     }
732 
733     // all of the bits match that were testable
734     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 id
766 #define getThreadId() syscall(__NR_gettid)
767 
768 // warning, by enabling this define you are aware that you are only delaying the inevitable
769 // some crashes are not recorable and those will stack up in time and lead to a full crash
770 // enabling this define will make windows servers shut down only the map instance in where the crash ocured
771 // during this forced shutdown players are not saved to avoid saving corrupted data
772 // there might be a lot of cases where each saved crash will lead to memory leaks or unhandled cases
773 // crashreports are still created and do use them to report the actaul problem that casued the crash
774 // fixing the problem that causes the crash is the proper way to fix things
775 //#define FORCED_SERVER_KEEPALIVE
776 
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);

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值