首页 > 其他分享 >【C/S通信交互之Socket篇】Cocos2dx(Client)使用BSD Socket与Mina(Server)手机网游通信框架!

【C/S通信交互之Socket篇】Cocos2dx(Client)使用BSD Socket与Mina(Server)手机网游通信框架!

时间:2022-11-24 14:34:15浏览次数:60  
标签:socketHandle Cocos2dx Socket 通信 Server Client Himi 数据



本站文章均为​ 李华明Himi ​​原创,转载务必在明显处注明:​​​​


其实对于此篇算是对于这段时间网络研究的一个总结。

对于手游网络通信的交互,一般情况下,Socket长连接直接使用Mina框架即可,对于Http短连接使用Servlet 入口即可(那么对于后期将陆续更新Servlet博文)

那么本篇主要介绍Socket长连接,当然与此配对的跨平台通信则选择了BSD Socket,当然还有其他的,这里只说BSD Socket;

对于BSD Socket不是很熟悉的请自行google学习下,Himi需要提醒大家的是BSD Socket不是第三方类库,而是UNIX/Linux系统中通用的网络接口;

首先连接到Server端,这里Himi简单封装一个函数提供大家使用;

     导入   #include <netdb.h>

两个参数:1:IP地址  2:端口

其中有个socket成员变量:

int socketHandle = 0;


​int​​ ​​HSocket::connect(​​ ​​const​​ ​​char​​ ​​* ip, unsigned ​​ ​​short​​ ​​port){  ​


 


​struct​​ ​​sockaddr_in sa;​


​struct​​ ​​hostent* hp;​


 


​hp = gethostbyname(ip);​


​if​​ ​​(!hp){​


​return​​ ​​-1;​


​}​


​memset​​ ​​(&sa, 0, ​​ ​​sizeof​​ ​​(sa));​


​memcpy​​ ​​((​​ ​​char​​ ​​*)&sa.sin_addr, hp->h_addr, hp->h_length);​


​sa.sin_family = hp->h_addrtype;​


​sa.sin_port = htons(port);​


 


​socketHandle = socket(sa.sin_family, SOCK_STREAM, 0);​


 


​if​​ ​​(socketHandle < 0){​


​printf​​ ​​( ​​ ​​"failed to create socket\n"​​ ​​);​


​return​​ ​​-1;​


​}​


​if​​ ​​(::connect(socketHandle, (sockaddr*)&sa, ​​ ​​sizeof​​ ​​(sa)) < 0){​


​printf​​ ​​( ​​ ​​"failed to connect socket\n"​​ ​​);​


​::close(socketHandle);​


​return​​ ​​-1;​


​}​


 


​CCLOG(​​ ​​"Client connect OK ! IP: %s:%d "​​ ​​,ip,port);​


​return​​ ​​0;​


​}​


两点注意:

1. 对于bsd socket 的  ::connect()函数进行连接服务器的时候会阻塞你的主线程,所以将Himi封装好的connect()函数在另一个线程调用则是一个好的处理方式;否则一旦网络比较差,你的游戏就假死ing~ 悲剧;

    2. 对于线程我们直接使用 pThread 就可以了,那么这里Himi就给一个创建线程的例子吧:

定义一个线程成员变量:

pthread_t threadHimi;

然后Himi也为大家封装一个函数:


​int​​ ​​HSocket::threadStart(){​


​int​​ ​​errCode = 0;​


​do​​ ​​{​


​pthread_attr_t tAttr;​


​errCode = pthread_attr_init(&tAttr);​


 


​CC_BREAK_IF(errCode!=0)​


 


​errCode = pthread_attr_setdetachstate(&tAttr, PTHREAD_CREATE_DETACHED);​


 


​if​​ ​​(errCode!=0) {​


​pthread_attr_destroy(&tAttr);​


​break​​ ​​;​


​}​


 


​errCode = pthread_create(&threadHimi, &tAttr, thread_function, ​​ ​​this​​ ​​);​


 


​}​​ ​​while​​ ​​(0);​


​return​​ ​​errCode;​


​}​


1)创建线程其实就是pthread_create()函数,但是上面这个函数其他内容则主要为你创建的线程设定为分离式;这里 thread_function 是个函数童鞋们对于pthread不太熟悉的请自行百度和google;

2)当然这里Himi要提醒大家,pthread是c库,不是c++库,它要求是全局函数,所以得static的!

那么连接到Server端之后我们就应该关心, BSD Socket  对于数据的发送和接收!

1.发送: send 函数:

           send(socketHandle,buffer,length,0)

socketHandle :  你已经连接的socket

buffer:发送的缓存数据

length:数据长度

2. 接收: recv 函数:

           recv(socketHandle, p, length, 0)

socketHandle  :  你已经连接的socket

p : 存放数据的容器

length:获取服务器数据的长度;

 注意:          

      1. 对于recv 函数的其中参数 length长度,大家务必要仔细,很清楚服务器应该发来的数据长度,因为一旦recv函数执行,那么不从Server端读取出length长度就不会罢休的!

 2.  如果你的Server端是Java的,那么要注意大端 ,小端的问题!Java属于大端模式,c++属于小端模式;(对于大小端不熟悉的,也请自行google,这里仍旧不赘述)

所以:

              Client->recv到数据后->数据转换成小端

              Client->send数据时->数据转换成大端

     这样才能保证Java服务器与cocos2dx的Client端正常交互;

—–上面一直在介绍Client端的知识,那么下面简单说下Server端Mina的相关知识吧——

其实对于Mina框架而言,功能强大使用简单,我们不需要关心通信,而只是需要关心数据的处理;当然对于数据的处理在Mina中最主要的就是取决于自定义的Decode 和 Encode,编码解码;

一般情况下定义好通信的数据结构,是比较关键的一点;

1. 比如一般数据都有数据头的概念,其中数据头用来标识当前通信的数据的版本,标识和真实数据的长度等等。(至于如何设计这个看大家自己的想法了);

2. 数据结构中更不能少的肯定还是协议号!根据协议号,客户端和服务器才能做同一件事情;

3. 当然其中我们还会使用MD5 或者 CRC等进行数据较验等,对于MD5和CRC校验不太熟悉的也请自行google = =。

定义好数据结构后,如同Client端与Server签订了合同,彼此遵循此结构进行交互;

Server端对于收发数据的处理其实在Mina中比较容易,通过Himi的Mina博文也可以清晰容易的懂得;但是如何能让服务器根据协议号找到对应的编码解码类去处理那么才是重点;Himi这里只简单提醒你创建一个抽象类;

OK,关于数据的存放,当然Himi这里使用的Hibernate 的Annotation映射到Mysql中。比较轻松愉快~

其实Himi以上说的虽然不是很详细,比如Client端对于Server端数据的细节处理等等;但是大概的手机网游框架和大家需要去掌握的知识点基本都没有遗漏,只要童鞋们对于文章中的所有知识点都了如指掌,OK。你Socket C/S手游框架即可开工;

下面Himi放出一张近来对于Server端的成绩图:

(Client 端:cocos2dx  /  Server端:Mina)

Client  特点: 当服务器端有数据发送给Client端,Client端自动将收到的数据索引到对应等待数据的类中;

Server 特点: 当客户端有数据发送Server端,Server端 能自动识别找到对应的编码解码类;

​​

 


标签:socketHandle,Cocos2dx,Socket,通信,Server,Client,Himi,数据
From: https://blog.51cto.com/xiaominghimi/5883905

相关文章

  • 【COCOS2DX-LUA 脚本开发之九】使用cocos2dx-LuaProxy便捷Lua项目快速使用cocos2dx引
    本站文章均为​​李华明Himi​​​原创,转载务必在明显处注明:(作者新浪微博:​​@李华明Himi​​​) width="150"height="210"framebo......
  • Android开发之线程间通信
    Android开发之线程间通信当我们的软件启动的时候,计算机会分配进程给到我们运行的程序,在进程中包含多个线程用于提高软件运行速度。在android网络请求中,我们知道在日常开......
  • [ Linux ] 进程间通信介绍 管道
    0.进程间通信介绍0.1通信背景在之前我们学习进程时知道进程具有独立性,所以进程间交互数据的成本就变得非常高。进程之间为什么也进行进程间通信,这就需要谈谈进程间通信的目......
  • WebSocket
    1、WebSocket基于TCP协议,支持二进制通信,双工通信。2、性能和并发能力更强。3、WebSocket独立于HTTP协议,不过我们一般仍然把WebSocket服务器端部署到Web服务器上,因为可以......
  • React 组件通信总结
    React组件通信总结父子通信传递数据(父传子)与传递方法(子传父)/**@Author:[email protected]*@Date:2022-11-2116:02:17*@LastEditors:Hua......
  • 进程间通信-IPC
    IPC进程间通信_顺其自然~的博客-CSDN博客_ipc通信1.进程间通信(IPC)——管道(36条消息)进程间通信(IPC)——管道_牵猫散步的鱼儿的博客-CSDN博客_ipc管道(37条消息)进程......
  • 主机与虚拟机之间的通信(ping命令)
    最近总是纠结于主机和虚拟机之间互ping的问题,当然了ping的统才能进行通信,就是这样一个神奇的命令。一开始不知道是怎么回事,经过自己的实践。把自己的小结总结如下,分享给大家......
  • 容器通信flannel和calico对比
    容器通信flannel和calico对比发布文章 Kubernetes跨主机容器之间的通信组件,目前主流的是flannel和calico,本文对两个组件进行简单介绍和对比。calico包括如下重要组件......
  • socket通信编程C++实现
    socket提供了套接字,以方便我们想读取文件一样进行网络进程间的数据通信。在网络通信中,套接字一定是成对出现的。一端的发送缓冲区对应对端的接收缓冲区。我们使用同一个文......
  • js和go对接websocket遇到的问题汇总
    TableofContentsgeneratedwithDocToc​​1.包协议​​​2.相关操作​​​2.1大端编码​​​​2.2大端解码​​​​2.3string转utf8-uint8Array[],utf8-uint8Arra......