TCP协议传输中的粘包和拆包

一 TCP协议的粘包和拆包说明

经常用tcp协议开发上位机或下位机的同事都会或多或少遇到粘包和拆包的问题,这是在网络通信中最常见的两个问题,这也与数据的发送和接收方式有关。

1 TCP粘包

指的是发送方发送的多个小数据包被接收方一次性接收的情况。这可能是因为发送方发送数据的速度过快,接收方无法及时处理,从而多个数据包被合并成一个大的数据包一起接收。

2 TCP拆包

指发送方发送的一个大数据包被接收方拆分成多个小的数据包接收的情况。这可能是由于网络中的路由器、交换机等设备的限制,导致大的数据包在传输过程中被分割成多个小的数据包。接收方需要能够正确地组装这些小数据包以还原原始的大数据包。

二 粘包与拆包造成的原因

粘包与拆包造成的原因是因为TCP是面向流的协议,数据是一连串的字节流,而不是消息边界明确的数据包

三 解决粘包

1 定长消息:

在每个消息之前添加消息长度的信息,接收方根据长度信息判断消息的边界。

java代码示例:

java 复制代码
// 发送端
int messageLength = 8; // 消息长度
String message = "68123456";
String formattedMessage = String.format("%-" + messageLength + "s", message);
outputStream.write(formattedMessage.getBytes());

// 接收端
byte[] buffer = new byte[messageLength];
int bytesRead = inputStream.read(buffer);
String receivedMessage = new String(buffer, 0, bytesRead);

2 分隔符:

使用特定的分隔符(如换行符或其他特殊字符)来标志消息的结束。

java代码示例:

java 复制代码
// 发送端
String message = "68123456\n";
outputStream.write(message.getBytes());

// 接收端
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String receivedMessage = reader.readLine();

3 消息头部包含长度信息:

在消息头部添加长度字段,表示后续消息的长度。

java 复制代码
// 发送端
String message = "68123456";
int messageLength = message.length();
outputStream.writeInt(messageLength);
outputStream.write(message.getBytes());

// 接收端
int receivedLength = inputStream.readInt();
byte[] buffer = new byte[receivedLength];
int bytesRead = inputStream.read(buffer);
String receivedMessage = new String(buffer, 0, bytesRead);

4 正则匹配:

使用正则表达式处理(不推荐),接入设备不同品牌可能存在上传的数据不是很标准的情况下可以使用完善处理,兼容报文数据格式。

java 复制代码
      // 模拟接收到的数据
        String receivedData = "68123456PP68123456PP68123456";

        // 定义正则表达式,假设消息之间使用 "PP" 作为分隔符
        String regex = "PP";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(receivedData);

        // 使用正则表达式切分消息
        while (matcher.find()) {
            String message = receivedData.substring(matcher.start(), matcher.end());
            System.out.println("Received message: " + message);
        }
相关推荐
津津有味道1 小时前
易语言TCP服务端接收刷卡数据并向客户端读卡器发送指令
服务器·网络协议·tcp·易语言
酣大智2 小时前
接口模式参数
运维·网络·网络协议·tcp/ip
Genie cloud2 小时前
1Panel SSL证书申请完整教程
服务器·网络协议·云计算·ssl
24zhgjx-lxq3 小时前
华为ensp:MSTP
网络·安全·华为·hcip·ensp
ling___xi3 小时前
《计算机网络》计网3小时期末速成课各版本教程都可用谢稀仁湖科大版都可用_哔哩哔哩_bilibili(笔记)
网络·笔记·计算机网络
REDcker3 小时前
Linux 文件描述符与 Socket 选项操作详解
linux·运维·网络
Up九五小庞3 小时前
用arpspoof实现100%批量切断192.168.110.10 - 192.168.110.100 断网(双向欺骗)--九五小庞
网络·开源
躺柒3 小时前
读数字时代的网络风险管理:策略、计划与执行04风险指引体系
大数据·网络·信息安全·数字化·网络管理·网络风险管理
独角鲸网络安全实验室4 小时前
本地信任成“致命漏洞”:数千Clawdbot Agent公网裸奔,供应链与内网安全告急
网络·网关·安全·php·漏洞·clawdbot·信任机制漏洞
ai_xiaogui4 小时前
Tailscale实现家庭与公司网络双向通信教程:子网路由配置详解
网络·tailscale·双向通信·子网路由配置详解·tailscale双向互访