如题。 各位在socket编程时,有没有在自定义的通信协议中设计包头?这个包头的设计需要考虑哪些因素呢?
例如,看到过一个网络程序中,自定义包头有如下两个字段: 8字节的自定义包头标识,CRC包头校验字段。那么,还需要考虑哪些字段?
补充问题:由于TCP协议本身就是非常可靠的,这样的包头标识和校验是否有必要呢?
表面上看起来,加帧标志是没有必要的,但你必须能够忍受网络的延时、中断等情况。
所以在实际应用时,如何区分一个包,不能仅仅依靠tcp协议。
一般情况,包头的主要目的是快速对数据流进行包分割。选用通信协议中不会使用的数据(可以是字节、字)作为包间隔是很有效的。如0x7E(内容中的0x7e\0x7d通过转义符0x7d转换为0x5e\0x5d),如果没有不会使用的数据,用使用概率尽量小的数据做包头,可以减轻检索包头的负担。
至于校验,不一定使用crc。如果帧结构的解析性良好,校验也可以不要。比如本人使用的一种包结构BOF LEN LEN BOF DATA SUM8 EOF(其中DATA是变长的),在使用GPRS网络传输的情况下,几百个接入,几百万个帧,校验出错计数为0,丢包率为0.3%左右。
TCP协议没有消息边界,因此在使用TCP协议的时候需要封装自己的应用层协议。一般来说,消除消息边界有这么几种可行的方法。
- 每次传输固定字节大小的数据,这样接收端知道接收到的“每一条”数据会有多大;
- 在传输数据之前加上自定义的标识,通常包括magic code,传输数据的字节长度,校验等;
- 还有一种方法是使用特定字节,标识数据到了末尾,比如"\r\n"等