Socket的半包,粘包与分包的问题

 

转载自:http://blog.csdn.net/kobejayandy/article/details/44632469

       关于半包、粘包和分包的现象产生,是因为TCP当中只有流的概念,没有包的概念. ,而面向流的通信是无消息保护边界的。由于TCP无消息保护边界, 需要在消息接收端处理消息边界问题,因此自然产生了如何分包。

半包
       接受方没有接受到一个完整的包,只接受了部分,这种情况主要是由于TCP为提高传输效率,将一个包分配的足够大,导致接受方并不能一次接受完。( 在长连接和短连接中都会出现)。

粘包与分包
       发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。出现粘包现象的原因是多方面的,它既可能由发送方造成,也可能由接收方造成。
       发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常TCP会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。
       接收方引起的粘包是由于接收方用户进程不及时接收数据,从而导致粘包现象。这是因为接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据尚未被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据之后,而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据。
       分包是指在出现粘包的时候我们的接收方要进行分包处理。(在长连接中都会出现)

什么时候需要考虑半包的情况?    
       Socket内部默认的收发缓冲区大小大概是8K,但是在实际中往往需要考虑效率问题,重新配置了这个值,来达到系统的最佳状态。
       一个实际中的例子:用mina作为服务器端,使用的缓存大小为10k,这里使用的是短连接,所有不用考虑粘包的问题。
       在并发量比较大的情况下,就会出现一次接受并不能完整的获取所有的数据。
       处理方式:
          1.通过包头+包长+包体的协议形式,当服务器端获取到指定的包长时才说明获取完整。
          2.指定包的结束标识,这样当我们获取到指定的标识时,说明包获取完整。  

什么时候需要考虑粘包的情况?    
       1.当时短连接的情况下,不用考虑粘包的情况;
       2.如果发送数据无结构,如文件传输,这样发送方只管发送,接收方只管接收存储就ok,也不用考虑粘包;
       3.如果双方建立连接,需要在连接后一段时间内发送不同结构数据。
       处理方式:
          接收方创建一预处理线程,对接收到的数据包进行预处理,将粘连的包分开。
       注:粘包情况有两种,一种是粘在一起的包都是完整的数据包,另一种情况是粘在一起的包有不完整的包。

 

在网络通信中,由于数据传输的特性,会出现粘包分包问题粘包(Packet Sticking)是指发送方发送的数据包被接收方连续接收到,多个数据包被黏在一起,导致接收方无法正确解析数据。这可能是因为发送方发送的数据包没有明确的边界,接收方无法确定每个数据包的开始和结束位置。 分包(Packet Splitting)是指发送方发送的数据包被接收方拆分成多个数据包接收。这可能是因为发送方发送的数据包过大,导致网络传输过程中被拆分成多个小包进行传输。 出现粘包分包问题的原因主要有以下几点: 1. 发送方连续发送多个数据包时,底层传输协议可能会将多个数据包合并成一个大的数据块进行传输,导致接收方接收到的数据不完整。 2. 发送方发送的数据包大小超过了接收方的缓冲区大小,导致数据被拆分成多个小包进行传输。 3. 网络传输中存在延迟或拥塞,导致数据包到达顺序发生变化。 为了解决粘包分包问题,可以采用以下几种方法: 1. 使用固定长度的数据包:在每个数据包的前面添加固定长度的头部信息,指示该数据包的长度,接收方根据头部信息来切分数据包。 2. 使用特殊字符作为分隔符:在数据包之间添加特殊字符作为分隔符,接收方根据分隔符来切分数据包。 3. 使用长度字段:在数据包的头部添加一个表示数据包长度的字段,接收方根据长度字段来切分数据包。 4. 使用消息边界:在传输协议中定义消息边界,保证每个数据包都是一个完整的消息。 具体选择哪种方法取决于你的应用需求和实际情况。在实际开发中,可以根据协议规范或业界常用的做法来处理粘包分包问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值