Socket封包、拆包、粘包

接触Socket通信的过程中,遇到了各种有关数据包的问题。这里做一下记录。

一、Socket粘包

1、什么是粘包?
答:顾名思义,其实就是多个独立的数据包连到一块儿。

2、什么情况下需要考虑粘包?
答:实际情况如下:

1、如果利用tcp每次发送数据,就与对方建立连接,然后双方发送完一段数据后,就关闭连接,这样就不会出现粘包问题。

2、如果发送的数据无结构,比如文件传输,这样发送方只管发送,接收方只管接收存储就ok,也不用考虑粘包。

3、如果双方建立连接,需要在连接后一段时间内发送不同结构数据,如连接后,有好几种结构:
1)”good good study”
2)”day day up”
那这样的话,如果发送方连续发送这个两个包出去,接收方一次接收可能会是”good good studyday day up” 这样接收方就傻了,因为协议没有规定这么奇怪的字符串,所以要把它分包处理,至于怎么分也需要双方组织一个比较好的包结构,所以一般可能会在头加一个数据长度之类的包,以确保接收。

所以说:Tcp连续发送消息的时候,会出现消息一起发送过来的问题,这时候需要考虑粘包的问题。

3、粘包出现的原因 (在流传输中,UDP不会出现粘包,因为它有消息边界。)

1、发送端需要等缓冲区满才发送出去,造成粘包 (发送端出现粘包)

2、接收端没有及时接收缓冲区包数据,造成一次性接收多个包,出现粘包 (接收端出现粘包)

4、解决粘包

1、缓冲区过大造成了粘包,所以在发送/接收消息时先将消息的长度作为消息的一部分发出去,这样接收方就可以根据接收到的消息长度来动态定义缓冲区的大小。(这种方法就是所谓的自定义协议,这种方法是最常用的)

2、对发送的数据进行处理,每条消息的首尾加上特殊字符,然后再把要发送的所有消息放入一个字符串中,最后将这个字符串发送出去,接收方接收到这个字符串之后,再通过特殊标记操作字符串,把每条消息截出来。(这种方法只适合数据量较小的情况)

注:要记住这一点:TCP对上层来说是一个流协议,所谓流,就是没有界限的一串数据.大家可以想想河里的流水,是连成一片的,其间是没有分界线的,也就是没有包的概念。所以我们必须自己定义包长或者分隔符来区分每一条消息。

二、Socket的封包、拆包

1、为什么基于TCP的通信程序需要封包、拆包?
答:TCP是流协议,所谓流,就是没有界限的一串数据。但是程序中却有多种不同的数据包,那就很可能会出现如上所说的粘包问题,所以就需要在发送端封包,在接收端拆包。

2、那么如何封包、拆包?
答:封包就是给一段数据加上包头或者包尾。比如说我们上面为解决粘包所使用的两种方法,其实就是封包与拆包的具体实现。

————————————-本文到此结束—————————————

你可能感兴趣的:(socket通信)