课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
tcp协议是程序员在学习计算机网络知识的时候会接触到的一个协议,而今天我们就通过案例分析来了解一下,网络通信时如何解决粘包问题。
网络通信程序实际开发中,或者技术面试时,面试官通常会问的比较多的一个问题是:网络通信时,如何解决粘包?
有的面试官可能会这么问:网络通信时,如何解决粘包、丢包或者包乱序问题?这个问题其实是面试官在考察面试者的网络基础知识,如果是TCP协议,在大多数场景下,是不存在丢包和包乱序问题的,TCP通信是可靠通信方式,TCP协议栈通过序列号和包重传确认机制保证数据包的有序和一定被正确发到目的地;如果是UDP协议,如果不能接受少量丢包,那就要自己在UDP的基础上实现类似TCP这种有序和可靠传输机制了(例如RTP协议、RUDP协议)。所以,问题拆解后,只剩下如何解决粘包的问题。
先来解释一下什么是粘包,所谓粘包就是连续给对端发送两个或者两个以上的数据包,对端在一次收取中可能收到的数据包大于1个,大于1个,可能是几个(包括一个)包加上某个包的部分,或者干脆就是几个完整的包在一起。当然,也可能收到的数据只是一个包的部分,这种情况一般也叫半包。
无论是半包还是粘包问题,其根源是上文介绍中TCP协议是流式数据格式。解决问题的思路还是想办法从收到的数据中把包与包的边界给区分出来。那么如何区分呢?目前主要有三种方法:
固定包长的数据包
顾名思义,即每个协议包的长度都是固定的。举个例子,例如我们可以规定每个协议包的大小是64个字节,每次收满64个字节,就取出来解析(如果不够,就先存起来)。
这种通信协议的格式简单但灵活性差。如果包内容不足指定的字节数,剩余的空间需要填充特殊的信息,如\0(如果不填充特殊内容,如何区分包里面的正常内容与填充信息呢?);如果包内容超过指定字节数,又得分包分片,需要增加额外处理逻辑——在发送端进行分包分片,在接收端重新组装包片(分包和分片内容在接下来会详细介绍)。
以指定字符(串)为包的结束标志
这种协议包比较常见,即字节流中遇到特殊的符号值时就认为到一个包的末尾了。例如,我们熟悉的FTP协议,发邮件的SMTP协议,一个命令或者一段数据后面加上"\r\n"(即所谓的CRLF)表示一个包的结束。对端收到后,每遇到一个”\r\n“就把之前的数据当做一个数据包。
这种协议一般用于一些包含各种命令控制的应用中,其不足之处就是如果协议数据包内容部分需要使用包结束标志字符,就需要对这些字符做转码或者转义操作,以免被接收方错误地当成包结束标志而误解析。
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。更多内容请在707945861群中学习了解。