加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Cocos2d-x中使用Socket方法总结

发布时间:2020-12-14 19:53:01 所属栏目:百科 来源:网络整理
导读:From: http://www.jb51.cc/article/p-xcrjsaew-za.html Socket又称"套接字",用于向网络发出请求或者应答网络请求 Socket工作的示意图: 程序实例:在Cocos2d-X中使用Socket 创建一个Sock类,用于处理Socket 在Sock.h中添加下面的代码 [cpp] view plain copy

From: http://www.52php.cn/article/p-xcrjsaew-za.html

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

Socket工作的示意图:

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

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

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

[cpp] view plain copy print ?
  1. #ifndef__Sock_H__
  2. #define__Sock_H__
  3. #ifdefWIN32
  4. #include<WinSock2.h>
  5. #defineSOCK_TYPESOCKET
  6. #else
  7. #defineSOCK_TYPEint
  8. #defineINVALID_SOCKET-1
  9. #endif
  10. #defineMyLog(...)
  11. //创建Sock类
  12. classSock
  13. {
  14. public:
  15. //构造函数
  16. Sock();
  17. //析构函数
  18. virtual~Sock();
  19. //设置成非阻塞模式
  20. boolsetNonBlock()
  21. {
  22. SOCK_TYPEfd=_fd;
  23. #ifdefWIN32
  24. BOOLflg=TRUE;
  25. //控制Socket的模式
  26. if(ioctlsocket(fd,FIONBIO,(unsignedlong*)&flg)!=0)
  27. {
  28. returnfalse;
  29. }
  30. returntrue;
  31. #else
  32. intflags=fcntl(fd,F_GETFL,0);
  33. flags|=O_NONBLOCK;
  34. returnfcntl(fd,F_SETFL,flags)!=-1;
  35. #endif
  36. }
  37. //关闭Sock
  38. voidclose()
  39. {
  40. #ifdefWIN32
  41. closesocket(_fd);
  42. #else
  43. ::close(_fd);
  44. #endif
  45. }
  46. voidattach(SOCK_TYPEfd)
  47. {
  48. _fd=fd;
  49. }
  50. //判断Sock是否合法
  51. boolisValidSocket()
  52. {
  53. return_fd!=INVALID_SOCKET;
  54. }
  55. protected:
  56. SOCK_TYPE_fd;
  57. };
  58. //客户端的Sock
  59. classSockClient:publicSock
  60. {
  61. public:
  62. //构造函数
  63. SockClient(unsignedshortport=0,constchar*ip=NULL)
  64. {
  65. if(port==0&&ip==NULL)
  66. {
  67. return;
  68. }
  69. //连接
  70. connect(port,ip);
  71. }
  72. //析构函数
  73. ~SockClient(){}
  74. //连接
  75. //第一个参数:端口
  76. //第二个参数:ip地址
  77. intconnect(unsignedshortport,constchar*ip)
  78. {
  79. //分配一个Socket
  80. //第一个参数:AF_INET表示指定地址族(地址描述)
  81. //第二个参数:SOCK_STREAM表示流式套接字TCP(Socket类型)
  82. //第三个参数:0(协议)
  83. _fd=socket(AF_INET,SOCK_STREAM,0);
  84. //地址信息结构
  85. structsockaddr_inaddr;
  86. //地址家族
  87. addr.sin_family=AF_INET;
  88. //端口号
  89. addr.sin_port=htons(port);
  90. //主机地址
  91. addr.sin_addr.s_addr=inet_addr(ip);
  92. //连接
  93. intret=::connect(_fd,(structsockaddr*)&addr,sizeof(addr));
  94. if(ret<0)
  95. {
  96. MyLog("connecterrorerrno=%d",errno);
  97. return-1;
  98. }
  99. return0;
  100. }
  101. //接收
  102. intrecv(char*buf,intlen)
  103. {
  104. return::recv(_fd,buf,len,0);
  105. }
  106. //发送
  107. intsend(constchar*buf,intlen)
  108. {
  109. return::send(_fd,0);
  110. }
  111. };
  112. //服务器端的Sock
  113. classSockServer:publicSock
  114. {
  115. public:
  116. //构造函数
  117. SockServer(unsignedshortport,constchar*ip=NULL)
  118. {
  119. //监听
  120. listen(port,ip);
  121. }
  122. //虚构函数
  123. ~SockServer(){}
  124. //接受连接
  125. SockClient*accept()
  126. {
  127. //接受客户端的发送请求,等待客户端发送connect请求
  128. SOCK_TYPEfd=::accept(_fd,NULL,NULL);
  129. if(fd!=INVALID_SOCKET)
  130. {
  131. //创建一个SockClient
  132. SockClient*ret=newSockClient;
  133. ret->attach(fd);
  134. returnret;
  135. }
  136. returnNULL;
  137. }
  138. protected:
  139. //监听
  140. //第一个参数:端口
  141. //第二个参数:ip地址
  142. intlisten(unsignedshortport,constchar*ip=NULL)
  143. {
  144. //分配一个Socket
  145. //第一个参数:AF_INET表示指定地址族(地址描述)
  146. //第二个参数:SOCK_STREAM表示流式套接字TCP(Socket类型)
  147. //第三个参数:0(协议)
  148. _fd=socket(AF_INET,0);
  149. //地址信息结果
  150. structsockaddr_inaddr;
  151. //地址家族
  152. addr.sin_family=AF_INET;
  153. //端口号
  154. addr.sin_port=htons(port);
  155. if(ip==NULL)
  156. {
  157. //设置一个不确定的ip地址
  158. addr.sin_addr.s_addr=INADDR_ANY;
  159. }
  160. else
  161. {
  162. //将ip地址转换为32位二进制网络字节序的IPV4地址
  163. addr.sin_addr.s_addr=inet_addr(ip);
  164. }
  165. //绑定
  166. intret=bind(_fd,sizeof(addr));
  167. if(ret<0)
  168. {
  169. MyLog("binderror");
  170. return-1;
  171. }
  172. //设置成非阻塞
  173. this->setNonBlock();
  174. //监听
  175. ::listen(_fd,10);
  176. return0;
  177. }
  178. };
  179. #endif

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

[cpp] view plain copy print ?
  1. #include"Sock.h"
  2. //构造函数
  3. Sock::Sock():_fd(INVALID_SOCKET)
  4. {
  5. #ifdefWIN32
  6. //初始化Windoes下的Sock
  7. staticboolwinInit=false;
  8. if(!winInit)
  9. {
  10. winInit=true;
  11. WSADATAdata;
  12. WSAStartup(MAKEWORD(2,2),&data);
  13. }
  14. #endif
  15. }
  16. //虚构函数
  17. Sock::~Sock()
  18. {
  19. if(isValidSocket())
  20. {
  21. close();
  22. }
  23. }


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

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

[cpp] view plain copy print ?
  1. #ifndef__SocketTest_H__
  2. #define__SocketTest_H__
  3. #include"cocos2d.h"
  4. #include"Sock.h"
  5. USING_NS_CC;
  6. classSocketTest:publicCCLayer
  7. {
  8. public:
  9. staticCCScene*scene();
  10. CREATE_FUNC(SocketTest);
  11. boolinit();
  12. SockServer*_server;
  13. SockClient*_client;
  14. //启动服务器
  15. voidmakeServer(CCObject*);
  16. //启动客服端
  17. voidmakeClient(CCObject*);
  18. //接受连接
  19. voidAccept(CCObject*);
  20. //发送
  21. voidSend(CCObject*);
  22. //接收
  23. voidRecv(CCObject*);
  24. };
  25. #endif

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

[cpp] view plain copy print ?
  1. #include"SocketTest.h"
  2. CCScene*SocketTest::scene()
  3. {
  4. CCScene*s=CCScene::create();
  5. SocketTest*layer=SocketTest::create();
  6. s->addChild(layer);
  7. returns;
  8. }
  9. boolSocketTest::init()
  10. {
  11. CCLayer::init();
  12. CCMenuItemFont*item1=CCMenuItemFont::create("MakeServer",this,menu_selector(SocketTest::makeServer));
  13. CCMenuItemFont*item2=CCMenuItemFont::create("MakeClient",menu_selector(SocketTest::makeClient));
  14. CCMenuItemFont*item3=CCMenuItemFont::create("Send",menu_selector(SocketTest::Send));
  15. CCMenuItemFont*item4=CCMenuItemFont::create("Recv",menu_selector(SocketTest::Recv));
  16. CCMenuItemFont*item5=CCMenuItemFont::create("Accept",menu_selector(SocketTest::Accept));
  17. CCMenu*menu=CCMenu::create(item1,item2,item3,item4,item5,NULL);
  18. addChild(menu);
  19. menu->alignItemsVertically();
  20. returntrue;
  21. }
  22. //启动服务器
  23. voidSocketTest::makeServer(CCObject*)
  24. {
  25. this->_server=newSockServer(9888);
  26. if(!this->_server->isValidSocket())
  27. {
  28. CCLog("serverERR");
  29. }
  30. else
  31. {
  32. CCLog("serverOK");
  33. }
  34. }
  35. //启动客服端
  36. voidSocketTest::makeClient(CCObject*)
  37. {
  38. this->_client=newSockClient(9888,"127.0.0.1");
  39. if(!this->_client->isValidSocket())
  40. {
  41. CCLog("ClientERR");
  42. }
  43. else
  44. {
  45. CCLog("ClientOK");
  46. }
  47. }
  48. //接受连接
  49. voidSocketTest::Accept(CCObject*)
  50. {
  51. this->_client=this->_server->accept();
  52. if(!this->_client->isValidSocket())
  53. {
  54. CCLog("AcceptERR");
  55. }
  56. else
  57. {
  58. CCLog("AcceptOK");
  59. }
  60. }
  61. //发送
  62. voidSocketTest::Send(CCObject*)
  63. {
  64. //发送信息
  65. intret=this->_client->send("Hello",6);
  66. CCLog("send:retis%d",ret);
  67. }
  68. //接收
  69. voidSocketTest::Recv(CCObject*)
  70. {
  71. charbuf[128];
  72. //接收信息
  73. intret=this->_client->recv(buf,sizeof(buf));
  74. CCLog("recvbufis%s",buf);
  75. }

执行结果:


测试SocketTest:

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

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

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


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



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

打印Accept Ok表示接受连接


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


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

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


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

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



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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读