文档章节

Java网络编程基础之TCP粘包拆包

端木轩
 端木轩
发布于 2017/09/10 20:15
字数 764
阅读 21
收藏 0

TCP是个“流”协议,所谓流,就是没有界限的一串数据。大家可以想象河里的流水,他们是连成一片的,其间并没有分界线。TCP底层并不了解上层业务数据的具体含义,他会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送。这就是TCP所谓的拆包和粘包的问题。

一、TCP粘包/拆包问题说明

我们可以通过图解对TCP粘包和拆包问题进行说明,粘包问题如图。

image

假设客户端分别发送了两个数据包D1和D2给服务端,由于服务端一次读取到的字节数是不确定的,故可能存在以下4中情况。

  • 服务端分两次读取到了两个独立的数据包,分别是D1和D2,没有粘包和拆包。
  • 服务端一次接收到了两个数据包,D1和D2粘在一起,被称为TCP粘包
  • 服务端分两次读取到了两个数据包,第一次读取到了完整的D1包和D2包的部分内容,第二次读取到了D2包的剩余内容,这被称为TCP拆包。
  • 服务端分两次读取到了两个数据包,第一次读取到了D1包的部分内容D1_1,第二次读取到了D1包的剩余内容D1_2和D2包的整包。

如果此时服务端TCP接收滑窗非常小,而数据包D1和D2比较大,很有可能会发生第五种可能,即服务端分多次才能将D1和D2包接收完全,期间发生多次拆包。

二、TCP粘包/拆包发生的原因

问题产生的原因有三个,分别如下。

  • 应用程序write写入的字节大小大于套接口发送缓冲区大小。
  • 进行MSS大小的TCP分段。
  • 以太网帧的payload大于MTU进行IP分片。

三、粘包问题的解决策略

由于底层的TCP无法理解上层的业务数据,所以在底层是无法保证数据包不被拆分和重组的,这个问题只能通过上层的应用协议栈设计来解决,根据业界的主流协议的解决方案,可以归纳如下。

  • 消息定长,例如每个报文的大小为固定长度200字节,如果不够,空位补空格
  • 在包尾增加回车换行符进行分割,例如FTP协议
  • 将消息分为消息头和消息体,消息头中包含表示消息总长度(或者消息体长度)的字段,通常涉及思路为消息头的第一个字段使用int32来表示消息的总长度
  • 更复杂的应用层协议。

本文转载自:

共有 人打赏支持
端木轩
粉丝 2
博文 42
码字总数 46549
作品 0
杭州
高级程序员
Netty(三) 什么是 TCP 拆、粘包?如何解决?

前言 记得前段时间我们生产上的一个网关出现了故障。 这个网关逻辑非常简单,就是接收客户端的请求然后解析报文最后发送短信。 但这个请求并不是常见的 HTTP ,而是利用 Netty 自定义的协议。...

crossoverJie
08/06
0
0
【Java】几道让你拿offer的知识点

前言 只有光头才能变强 之前在刷博客的时候,发现一些写得比较好的博客都会默默收藏起来。最近在查阅补漏,有的知识点比较重要的,但是在之前的博客中还没有写到,于是趁着闲整理一下。 文本...

Java3y
08/02
0
0
【Java】几道让你拿offer的面试题

只有光头才能变强 之前在刷博客的时候,发现一些写得比较好的博客都会默默收藏起来。最近在查阅补漏,有的知识点比较重要的,但是在之前的博客中还没有写到,于是趁着闲整理一下。 文本的知识...

Java3y
08/02
0
0
通信(Netty、Mina2)【通信粘包的处理】、【数据协议】、【网络系统的安全性】

Netty、Mina2是非常优秀的javaNIO+ThreadPool线程池通信框架http://www.cnblogs.com/51cto/archive/2010/09/06/1819361.html提到通信就得面临两个问题,一是通信协议的选择,二是数据协议的定...

干死it
2014/06/24
0
0
Netty5入门学习笔记001

Netty官网:http://netty.io/ 本例程使用最新的netty5.x版本编写 服务器端: TimeServer 时间服务器 服务端接收客户端的连接请求和查询当前时间的指令,判断指令正确后响应返回当前服务器的校...

山东-小木
2014/12/17
0
10

没有更多内容

加载失败,请刷新页面

加载更多

下一页

ES6 Promise

Promise promise是异步编程的一种解决方案 1 什么是异步? 异步模式,每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则...

NDweb
20分钟前
0
0
Python百分登顶年度编程语言排行榜

今天 IEEE Spectrum 发布了 2018 年度顶级编程语言排行榜。该榜单可根据流行趋势、职业方向、语言类型等多个标准各自细分生成榜单,也可以综合多个标准进行排列,使用者可以根据自己的需求过...

六库科技
24分钟前
0
0
consul笔记

安装和启动就不说了,很简单。 注册一个服务: http://localhost:8500/v1/agent/service/register put请求,json格式内容如下 { "ID": "userServiceId", //服务id "Name": "userService", //服...

朝如青丝暮成雪
24分钟前
0
0
iOS CollectionView 的那些事

UICollectionView是开发中用的比较多的一个控件,本文记录UICollectionView在开发中常用的方法总结,包括使用UICollectionViewFlowLayout实现Grid布局、添加Header/Footer、自定义layout布局...

aron1992
24分钟前
0
0
linux tar.gz zip 解压缩 压缩命令

http://apps.hi.baidu.com/share/detail/37384818 download ADT link http://dl.google.com/android/ADT-0.9.6.zip download SDK link http://dl.google.com/Android/android-sdk_r11-linux_......

owensliu
26分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部