关于消息封包和拆包

消息有多种,在应用层、传输层、链路层等都有各自的消息封包。

在应用中可能客户端程序需要把一个很大的结构化数据传输到远程服务器,进行数据存储,这涉及到各种消息的封包和拆包。

应用层需要把结构化的数据,打包成字节流,加上应用层的数据戳,包括序列化的数据大小、类型、描述信息等。

应用层序列化后的字节数据,可能很大,我们需要通过网络传输,但在传输层的发送缓冲区都是有一定的限制的,即使发送缓冲区无穷大,在传输的协议层由于各种协议的限制,也是对每次数据包的传输有限制,TCP可能传输很大的数据包,因为底层的滑动窗口协议可以做协议保证,但是UDP做为组播数据,就没法保证了。

到了链路层,所有的传输层数据需要打上地址信息,这需要拆分成更小的包了,这不仅是链路层协议所限制,更由于实际的网路路由环境和带宽所限制。更小的封包才能保证在多个路由上传输和需要更小的带宽。

到了服务器端,由于需要还原到原始的结构化数据,则需要对所有的过程进行反向处理,进行组包和反序列化。

在实际的应用中,因为传输层和链路层,都由操作系统和路由设备辅助实现了,我们在进行远程通信时,主要关心的是应用层的消息封包和拆包,为了迎合传输层对发送数据的要求,在应用层的消息封包时,一般大于发送缓冲区的数据封包,需要拆解开,但是为了便于进行组包,需要在拆包中加入特定的序列号,这样在服务器端进行组包时,可以根据序列重组,同时为了达到数据的自校验目的,需要加入对应的校验和算法,尤其是在利用UDP或串口等传输数据时,因为其无TCP的自我保护机制,更需要进行应用层的算法校验。

因为数据的一些描述信息,所占的容量都很小,比如数据长度,数据头描述等,因此该部分我们可以作为独立封包处理,这样远程服务器收到该封包确认后,我们就可以进行实际数据部分的发送了,因为所有的描述信息,都在头数据包中有了,数据体的接收就可以更有针对性了。Http协议作为应用层协议,就采用了上述的封包处理,请求时首先是获取到的头描述信息,浏览器在获取到了具体的头描述信息后,就可以有针对性的加载数据体信息了。


你可能感兴趣的:(关于消息封包和拆包)