(四)什么是TCP拆包、粘包?如何解决?

一、TCP协议

TCP是一个面向字节流的协议,它的性质是流式的,所以它并没有分段。就像水流一样,你没法知道什么时候开始,什么时候结束。

所以他会根据当前的套接字缓冲区的情况进行拆包或是粘包。

发送端的字节流都会先传入缓冲区,再通过网络传入到接收端的缓冲区中,最终由接收端获取。

 

 

二、拆包、粘包

当我们发送两个完整包到接收端的时候:

正常情况会接收到两个完整的报文。

 

但也有以下的情况:

接收到的是一个报文,它是由发送的两个报文组成的,这样对于应用程序来说就很难处理了(这样称为粘包)。

 

还有可能出现上面这样的,虽然收到了两个包,但是里面的内容却是互相包含,对于应用来说依然无法解析(这样称为拆包)。

 

 

三、解决方式

对于这样的问题只能通过上层的应用来解决,常见的方式有:

  • 在报文末尾增加换行符表明一条完整的消息,这样在接收端可以根据这个换行符来判断消息是否完整。
  • 将消息分为消息头、消息体。可以在消息头中声明消息的长度,根据这个长度来获取报文(比如808协议)。
  • 规定好报文长度,不足的空位补齐,取的时候按照长度截取即可。

以上的这些方式我们在Netty的pipline中加入对应的解码器都可以手动实现。

但其实Netty已经帮我们做好了,完全可以开箱即用。

比如:

  • LineBasedFrameDecoder可以基于换行符解决。
  • DelimiterBasedFrameDecoder可以基于分隔符解决。
  • FixedLengthFrameDecoder可以指定长度解决。

 

上面提到的其实就是在解码中进行操作,我们也可以自定义自己的拆、粘包工具。

编解码的主要目的就是为了可以编码成字节流用于在网络中传输、持久化存储。

java中也可以实现serializable接口来实现序列化,但由于它性能等原因在一些RPC调用中用的很少。

Google Protocol Buffer(protobuf)则是一个高效的序列化框架。

下载安装protobuf后,可以定义自己的协议格式,自动生成自定义协议格式java代码(编解码都封装好了)。

Netty已经自带了对protobuf的编解码器,只需要在pipline中添加即可。

 

 

具体原理及使用请前往https://crossoverjie.top/2018/08/03/netty/Netty(3)TCP-Sticky/,本文学习借鉴自此文章。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值