0
点赞
收藏
分享

微信扫一扫

网络编程(8)自定义网络通讯协议


        C/C++网络通讯真正要用起来,不但要写一个好的网络服务器,还要定好一套通讯协议才能真正实用。
通讯协议业界目前除了用开源的如XMPP以外,基本上都是自定义一套通讯协议,自已负责封包,拆包。
为什么要自己定义协议包呢?一个原因是因为真正的业务逻辑往往都是复杂的,不会是很单纯的字符串或数字。再参考前面写的<< ​​网络编程(7)字节序对跨平台数据传输的影响​​>>就应当知道,通讯时网络传输是以字节为单位的。这一串串数据流在交互,如何能在数据流每次交互中正确识别出,
真正有用的东西,就要双方定义一套方法。发送方把要传输的东东放在一起定义好包,转成网络字节序发送出去。接收方收到后,再按包的定义,拆解出有用的数据。

包定义各有各的搞法,但通常会包含下面几部份:
 :用于业务逻辑区分
     内容长度  :  传输数据的长度
    消息内容  :  本次实际要传输的数据
    校验位


包通常都是结构体,可以这样定义:

typedef struct _Packet{
unsigned short pkg_type;
unsigned int pkg_len;
char pkg_content[pkg_len];
unsigned short pkg_cs;
}Packet;


也可以这样:


typedef struct _PacketHeader{
unsigned short pkg_type;
unsigned short pkg_len;
}PacketHeader;

typedef struct _PacketBody{
struct _PacketHeader pkg_header;
char pkg_content[pkg_len];
......
}Packet;

或者其它别的方式。


通常都会用宏或函数将这些结构体即

包体内容转成网络字节序(char)转给接收方,接收方再去解析它们即解包。


前面说了定义包的一个原因,另外原因之一是,在数据传输中,并不老是一帆风顺能得到你想要的


结果的,可能会出现其它意外,倒致你没有收到完整的数据,或收到的数据不是你想要的。而完善的通讯协议能


有效的检测完整性和区分出你想要的数据。


列几种例外情况


粘包: tcp为了提高效率(使用Nagle算法)会缓冲N个包后再一起发出去.


分包: 数据不全,数据不是一次,而是分几次到达。


非法包: 传过来的数据流不符合协议。这个要通过比较包类型,包长,效验位去检测出来。



 总之要弄个实用的网络通讯要考虑的东东很多,要写好这类程序真的很难。







举报

相关推荐

0 条评论