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

简介:

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

对于手游网络通信的交互,一般情况下,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;

 

 
 
  1. int HSocket::connect(const char* ip, unsigned short port){   
  2.  
  3.     struct sockaddr_in sa; 
  4.     struct hostent* hp; 
  5.  
  6.     hp = gethostbyname(ip); 
  7.     if(!hp){ 
  8.         return -1
  9.     } 
  10.     memset(&sa, 0, sizeof(sa)); 
  11.     memcpy((char*)&sa.sin_addr, hp->h_addr, hp->h_length); 
  12.     sa.sin_family = hp->h_addrtype; 
  13.     sa.sin_port = htons(port); 
  14.  
  15.     socketHandle = socket(sa.sin_family, SOCK_STREAM, 0); 
  16.  
  17.     if(socketHandle < 0){ 
  18.         printf( "failed to create socket\n" ); 
  19.         return -1
  20.     } 
  21.     if(::connect(socketHandle, (sockaddr*)&sa, sizeof(sa)) < 0){ 
  22.         printf( "failed to connect socket\n" ); 
  23.         ::close(socketHandle); 
  24.         return -1
  25.     } 
  26.  
  27.     CCLOG("Client connect OK ! IP: %s:%d ",ip,port); 
  28.     return 0

两点注意:

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

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

定义一个线程成员变量:

pthread_t threadHimi;

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

 

 
 
  1. int HSocket::threadStart(){ 
  2.     int errCode = 0
  3.     do
  4.         pthread_attr_t tAttr; 
  5.         errCode = pthread_attr_init(&tAttr); 
  6.  
  7.         CC_BREAK_IF(errCode!=0
  8.  
  9.         errCode = pthread_attr_setdetachstate(&tAttr, PTHREAD_CREATE_DETACHED); 
  10.  
  11.         if (errCode!=0) { 
  12.             pthread_attr_destroy(&tAttr); 
  13.             break
  14.         } 
  15.  
  16.         errCode = pthread_create(&threadHimi, &tAttr, thread_function, this); 
  17.  
  18.     }while (0); 
  19.     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端 能自动识别找到对应的编码解码类;

 










本文转自 xiaominghimi 51CTO博客,原文链接:http://blog.51cto.com/xiaominghimi/969793,如需转载请自行联系原作者
目录
相关文章
|
Java Apache
学习socket nio 之 mina实例(1)
学习socket nio 之 mina实例(1)
114 0
学习socket nio 之 mina实例(1)
|
编解码 Java 网络安全
Socket网络框架 MINA
引用:http://apps.hi.baidu.com/share/detail/31519395 http://apps.hi.baidu.com/share/user/65276d79647265616d5f7869616f3608 MINA是一个网络应用框架,在不牺牲性能和可扩展性的前提下用于解决如下问题:1: 快速开发自己的英勇。
921 0
|
27天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
27天前
|
程序员 开发者 Python
Python网络编程基础(Socket编程) 错误处理和异常处理的最佳实践
【4月更文挑战第11天】在网络编程中,错误处理和异常管理不仅是为了程序的健壮性,也是为了提供清晰的用户反馈以及优雅的故障恢复。在前面的章节中,我们讨论了如何使用`try-except`语句来处理网络错误。现在,我们将深入探讨错误处理和异常处理的最佳实践。
|
27天前
|
Python
Python网络编程基础(Socket编程) 使用try-except处理网络错误
【4月更文挑战第11天】在网络编程中,错误处理和异常管理是非常重要的部分。网络操作经常因为各种原因而失败,比如网络断开、服务器无响应、地址不正确等。因此,学会如何使用Python的异常处理机制来捕获和处理这些错误,是编写健壮的网络应用的关键。
|
28天前
|
网络协议 网络安全 Python
Python网络编程基础(Socket编程) 错误处理和异常
【4月更文挑战第10天】网络编程涉及到很多复杂的操作和潜在的风险,如连接失败、数据丢失、超时等问题。因此,正确的错误处理和异常捕获是确保网络程序稳定性和可靠性的关键。本章将介绍网络编程中常见的错误和异常,并探讨如何在Python中进行有效的错误处理。
|
28天前
|
存储 Python
Python网络编程基础(Socket编程) UDP 发送和接收数据
【4月更文挑战第10天】对于UDP客户端而言,发送数据是一个相对简单的过程。首先,你需要构建一个要发送的数据报,这通常是一个字节串(bytes)。然后,你可以调用socket对象的`sendto`方法,将数据报发送到指定的服务器地址和端口。
|
29天前
|
存储 Python
Python网络编程基础(Socket编程)UDP客户端编程
【4月更文挑战第9天】在UDP通信中,客户端负责发送数据到服务器,并接收来自服务器的响应。与服务器不同,客户端通常不需要绑定到特定的地址和端口,因为它可以临时使用任何可用的端口来发送数据。下面,我们将详细讲解UDP客户端编程的基本步骤。
|
29天前
|
Python
Python网络编程基础(Socket编程)绑定地址和端口
【4月更文挑战第9天】在UDP服务器编程中,我们首先需要创建一个UDP套接字,然后绑定一个本地地址和端口,以便客户端可以通过这个地址和端口与我们的服务器进行通信。下面,我们将详细讲解如何绑定地址和端口。