博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Cocos2d-x中使用Socket方法总结
阅读量:6921 次
发布时间:2019-06-27

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

Borrowed from:

Socket又称"套接字",用于向网络发出请求或者应答网络请求。

Socket工作的示意图:

20141126105414969.jpg

程序实例:在Cocos2d-X中使用Socket

创建一个Sock类,用于处理Socket

在Sock.h中添加下面的代码

#ifndef __Sock_H__#define __Sock_H__ #ifdef WIN32#include 
#define SOCK_TYPE SOCKET#else#define SOCK_TYPE int#define INVALID_SOCKET -1#endif #define MyLog(...)  //创建Sock类class Sock{public:    //构造函数    Sock();     //析构函数    virtual ~Sock();     //设置成非阻塞模式    bool setNonBlock()    {        SOCK_TYPE fd = _fd; #ifdef WIN32        BOOL flg = TRUE;         //控制Socket的模式        if(ioctlsocket(fd, FIONBIO, (unsigned long *)&flg) != 0)        {            return false;        }         return true; #else        int flags = fcntl(fd, F_GETFL, 0);        flags |= O_NONBLOCK;        return fcntl(fd, F_SETFL, flags) != -1;#endif    }     //关闭Sock    void close()    {#ifdef WIN32        closesocket(_fd);#else        ::close(_fd);#endif    }     void attach(SOCK_TYPE fd)    {        _fd = fd;     }     //判断Sock是否合法    bool isValidSocket()    {        return _fd != INVALID_SOCKET;     } protected:         SOCK_TYPE _fd;};  //客户端的Sockclass SockClient : public Sock{public:    //构造函数    SockClient(unsigned short port = 0, const char* ip = NULL)    {        if (port == 0 && ip == NULL)        {            return;        }         //连接        connect(port, ip);    }     //析构函数    ~SockClient(){}          //连接    //第一个参数:端口   //第二个参数:ip地址    int connect(unsigned short port, const char* ip)    {        //分配一个Socket        //第一个参数:AF_INET表示指定地址族(地址描述)        //第二个参数:SOCK_STREAM表示流式套接字TCP(Socket类型)        //第三个参数:0(协议)        _fd = socket(AF_INET, SOCK_STREAM, 0);         //地址信息结构        struct sockaddr_in addr;                 //地址家族        addr.sin_family = AF_INET;         //端口号        addr.sin_port = htons(port);         //主机地址        addr.sin_addr.s_addr = inet_addr(ip);         //连接        int ret = ::connect(_fd, (struct sockaddr*)&addr, sizeof(addr));                 if (ret < 0)        {            MyLog("connect error errno=%d", errno);            return -1;        }         return 0;    }     //接收    int recv(char* buf, int len)    {        return ::recv(_fd, buf, len, 0);    }     //发送    int send(const char* buf, int len)    {        return ::send(_fd, buf, len, 0);    }}; //服务器端的Sockclass SockServer :public Sock{public:    //构造函数    SockServer(unsigned short port, const char* ip = NULL)    {        //监听        listen(port, ip);    }     //虚构函数    ~SockServer(){}     //接受连接    SockClient* accept()    {        //接受客户端的发送请求,等待客户端发送connect请求        SOCK_TYPE fd = ::accept(_fd, NULL, NULL);                 if (fd != INVALID_SOCKET)        {            //创建一个SockClient            SockClient* ret = new SockClient;            ret->attach(fd);            return ret;        }        return NULL;    } protected:    //监听    //第一个参数:端口    //第二个参数:ip地址    int listen(unsigned short port, const char* ip = NULL)    {          //分配一个Socket        //第一个参数:AF_INET表示指定地址族(地址描述)        //第二个参数:SOCK_STREAM表示流式套接字TCP(Socket类型)        //第三个参数:0(协议)        _fd = socket(AF_INET, SOCK_STREAM, 0);         //地址信息结果        struct sockaddr_in addr;         //地址家族        addr.sin_family = AF_INET;         //端口号        addr.sin_port = htons(port);                 if (ip == NULL)        {            //设置一个不确定的ip地址            addr.sin_addr.s_addr = INADDR_ANY;        }        else        {            //将ip地址转换为32位二进制网络字节序的IPV4地址            addr.sin_addr.s_addr = inet_addr(ip);        }         //绑定        int ret = bind(_fd, (struct sockaddr*)&addr, sizeof(addr));                 if (ret < 0)        {            MyLog("bind error");            return -1;        }         //设置成非阻塞        this->setNonBlock();         //监听        ::listen(_fd, 10);         return 0;    }}; #endif

在Sock.cpp中添加下面的代码

#include "Sock.h" //构造函数Sock::Sock() :_fd(INVALID_SOCKET){ #ifdef WIN32         //初始化Windoes下的Sock    static bool winInit = false;    if (!winInit)    {        winInit = true;         WSADATA data;        WSAStartup(MAKEWORD(2, 2), &data);    }#endif}  //虚构函数Sock::~Sock(){    if (isValidSocket())    {        close();    }}

再创建一个SocketTest类,用于测试Socket

在SocketTest.h中添加下面的代码

#ifndef __SocketTest_H__#define __SocketTest_H__ #include "cocos2d.h"#include"Sock.h"USING_NS_CC;   class SocketTest : public CCLayer {public:    static CCScene* scene();     CREATE_FUNC(SocketTest);    bool init();     SockServer* _server;    SockClient* _client;     //启动服务器    void makeServer(CCObject*);     //启动客服端    void makeClient(CCObject*);     //接受连接    void Accept(CCObject*);     //发送    void Send(CCObject*);     //接收    void Recv(CCObject*); }; #endif

在SocketTest.cpp中添加下面的代码

#include "SocketTest.h"  CCScene* SocketTest::scene(){    CCScene* s = CCScene::create();    SocketTest* layer = SocketTest::create();    s->addChild(layer);    return s;}  bool SocketTest::init(){    CCLayer::init();     CCMenuItemFont* item1 = CCMenuItemFont::create("MakeServer", this, menu_selector(SocketTest::makeServer));    CCMenuItemFont* item2 = CCMenuItemFont::create("MakeClient", this, menu_selector(SocketTest::makeClient));    CCMenuItemFont* item3 = CCMenuItemFont::create("Send", this, menu_selector(SocketTest::Send));    CCMenuItemFont* item4 = CCMenuItemFont::create("Recv", this, menu_selector(SocketTest::Recv));    CCMenuItemFont* item5 = CCMenuItemFont::create("Accept", this, menu_selector(SocketTest::Accept));    CCMenu* menu = CCMenu::create(item1, item2, item3, item4, item5, NULL);    addChild(menu);    menu->alignItemsVertically();         return true;}  //启动服务器void SocketTest::makeServer(CCObject*){    this->_server = new SockServer(9888);         if (!this->_server->isValidSocket())    {        CCLog("server ERR");    }    else    {        CCLog("server OK");    }}  //启动客服端void SocketTest::makeClient(CCObject*){    this->_client = new SockClient(9888, "127.0.0.1");         if (!this->_client->isValidSocket())    {        CCLog("Client ERR");    }    else    {        CCLog("Client OK");    }}  //接受连接void SocketTest::Accept(CCObject*){    this->_client = this->_server->accept();         if (!this->_client->isValidSocket())    {        CCLog("Accept ERR");    }    else    {        CCLog("Accept OK");    }}  //发送void SocketTest::Send(CCObject*){    //发送信息    int ret = this->_client->send("Hello", 6);    CCLog("send: ret is %d", ret);}  //接收void SocketTest::Recv(CCObject*){    char buf[128];     //接收信息    int ret = this->_client->recv(buf, sizeof(buf));    CCLog("recv buf is %s", buf);}

执行结果:

1417056090890222.jpg

测试SocketTest:

启动两个SocketTest程序,一个做服务器,一个做客户端。

服务器上单击makeServer,启动服务器

1417056163731456.jpg

打印Server Ok表示服务器启动成功

20141126111857953.jpg                                                              

客户端单击makeClient,启动客户端

20141126112032958.jpg

服务器上单击Accept,连接客户端

20141126112240640.jpg

打印Accept Ok表示接受连接

20141126112356000.png

客户端单击Send,客户端发送消息到服务器

20141126112438612.jpg

服务器上单击Recv,接收服务器上发来的消息

20141126112529687.jpg

打印出了"recv buf is Hello"表示服务器上收到了客户端发送的消息

20141126112911359.png

服务器上单击Send,服务器发送消息到客户端

20141126112942875.jpg

打印出了“send: ret is 6”表示服务器成功的向客户端发送了一个消息

20141126113202136.png

客服端上单击Recv,客户端接收服务器发来的消息

20141126113300433.jpg

推荐阅读:

转载地址:http://arzjl.baihongyu.com/

你可能感兴趣的文章
2015年度精品 最新力作32位和64位xp,win7,win8,win10系统下载(电脑城专用版)
查看>>
hdu Wooden Sticks
查看>>
图像分类学习笔记
查看>>
Python学习笔记(二)
查看>>
语音信号处理之(一)动态时间规整(DTW)
查看>>
Python3 operator模块关联代替Python2 cmp() 函数
查看>>
温故知新系列(一)冒泡排序
查看>>
Web服务之LNMMP架构及动静分离实现
查看>>
java作业6
查看>>
从基础到分析,聊一聊企业报表平台的建设规划!
查看>>
java中的AIO
查看>>
混合云已到来,企业用户们你们准备好了吗?
查看>>
【超详细教程】使用Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结...
查看>>
HomeAccess Ha910设置自动拨号
查看>>
备忘录方法与动态规划比较
查看>>
BZOJ3157: 国王奇遇记 & 3516: 国王奇遇记加强版
查看>>
KNN分类算法补充
查看>>
1、单例模式(饿汉/懒汉)
查看>>
poj 3273 Monthly Expense(二分穷举)
查看>>
RH253读书笔记(8)-Lab 8 Securing Data
查看>>