tcp粘包,断包问题及处理
做过一个五子棋大作战游戏,当时用socket长连接在人人联网对战时进行处理,但在游戏过程中总会出现两个下棋的人接收不到对方棋子的落点的信息,这就是典型的出现了tcp粘包问题。
下来进行具体说明。
1.理解Nagle算法
当发送方每次发送的数据包都比较小时,而这种小的数据包又比较多时,就会导致网络拥塞,瘫痪,为了处理这种问题引入Nagle算法。Nagle算法:发送方首先会发送第一个小数据包,并将其余的小数据包放入其缓存中,等到收到接收方的ACK时,便将这些小数据包一块发送过去。
2.Nagle算法带来的问题-粘包
当后面的小数据包一块发送的时候,就可能造成粘包现象,例如我们五子棋的自定义协议是包头+数据:第一个包{type:0,username:”wp”,”password”:”www”}
第二个包::{type:1,x:1,y:1}
第三个包::{type:1,x:2,y:1}
这样会造成二三包粘包,接收方会接收到{type:1,x:1,y:1}{type:1,x:2,y:1},这样就无法解析处理了。
3.解决粘包问题
<1>接收方在包头记录此次发送包的大小,接收方根据包头的写的包大小,对包进行截取处理。
<2>在包结尾处添加特殊字符,接收方根据此特殊字符进行处理。
对于socket最简单的方法就是 socket.setTcpNoDelay(true); 来禁用Nagle算法。
4.断包问题
断包问题,就是一次发送的包过大,导致发送方缓冲区存不下,就会进行截取发送,导致包不连续。
断包的处理和粘包的处理一样(就上面的两种方法)。