通讯协议业界目前除了用开源的如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个包后再一起发出去.
分包: 数据不全,数据不是一次,而是分几次到达。
非法包: 传过来的数据流不符合协议。这个要通过比较包类型,包长,效验位去检测出来。
总之要弄个实用的网络通讯要考虑的东东很多,要写好这类程序真的很难。
MAIL: xcl_168@aliyun.com
BLOG: http://blog.csdn.net/xcl168