Java Socket通信基础及拆包粘包问题模拟(上)

devtools/2025/3/14 23:10:42/

一、Socket通信基础概念

1.1 什么是Socket?

Socket(套接字)是计算机网络中不同主机间进程进行双向通信的端点,本质是操作系统提供的进程间通信机制。它封装了TCP/IP协议栈的复杂操作,为应用程序提供了标准API。

1.2 TCP协议特性

  • 面向连接的可靠传输协议
  • 保证数据顺序到达
  • 基于字节流的传输(无消息边界)
  • 流量控制和拥塞控制机制

1.3 通信要素

  • IP地址:定位网络中的主机
  • 端口号:标识主机中的具体应用
  • 协议类型:TCP/UDP

二、Java Socket基础实现

2.1 服务端实现

java">public class SimpleServer {public static void main(String[] args) throws IOException {// 创建服务端Socket并绑定端口try (ServerSocket serverSocket = new ServerSocket(8888)) {System.out.println("服务端启动,等待连接...");// 接受客户端连接try (Socket clientSocket = serverSocket.accept();BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {System.out.println("客户端已连接");String receivedMsg;// 持续读取客户端数据while ((receivedMsg = in.readLine()) != null) {System.out.println("收到消息:" + receivedMsg);}}}}
}

2.2 客户端实现

java">public class SimpleClient {public static void main(String[] args) throws IOException {// 连接服务端try (Socket socket = new Socket("localhost", 8888);PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {System.out.println("已连接到服务端");// 发送测试消息out.println("Hello Server!");out.println("This is a test message.");}}
}

三、拆包与粘包现象模拟

3.1 问题现象说明

  • 粘包:多个数据包被接收方一次性接收
  • 拆包:一个数据包被拆分成多次接收

3.2 客户端改造(模拟快速发送)

java">public class PacketIssueClient {public static void main(String[] args) throws IOException, InterruptedException {try (Socket socket = new Socket("localhost", 8888);OutputStream out = socket.getOutputStream()) {// 连续发送小数据包for (int i = 0; i < 5; i++) {String msg = "Msg-" + i + "\n";  // 注意换行符out.write(msg.getBytes());System.out.println("已发送:" + msg.trim());Thread.sleep(500);  // 降低发送速度}// 发送大数据包(超过缓冲区)StringBuilder bigData = new StringBuilder();for (int i = 0; i < 100; i++) {bigData.append("ABCDEFGHIJ");}out.write(bigData.toString().getBytes());}}
}

3.3 服务端改造(原始读取方式)

java">public class RawDataServer {public static void main(String[] args) throws IOException {try (ServerSocket serverSocket = new ServerSocket(8888)) {System.out.println("服务端启动...");try (Socket clientSocket = serverSocket.accept();InputStream in = clientSocket.getInputStream()) {byte[] buffer = new byte[1024];int bytesRead;// 原始字节流读取while ((bytesRead = in.read(buffer)) != -1) {String received = new String(buffer, 0, bytesRead);System.out.println("收到原始数据:\n" + received);}}}}
}

3.4 运行结果示例

收到原始数据:
Msg-0
Msg-1
Msg-2
收到原始数据:
Msg-3
Msg-4
ABCDEFGHIJABCDEF...
收到原始数据:
...(剩余数据)

四、现象分析

  1. 粘包产生:客户端快速发送多个小包时,服务端可能一次性读取多个消息
  2. 拆包出现:当发送大数据包时,由于接收缓冲区限制,数据被分割成多次读取
  3. 根本原因:TCP是字节流协议,不维护消息边界

五、下篇预告

在下一篇中,我们将深入探讨如何解决拆包/粘包问题,包括:

  • 定长消息解码器实现
  • 特殊分隔符处理方案
  • 基于长度字段的编解码器
  • 使用主流框架(Netty)的解决方案

思考题:为什么UDP协议不存在拆包/粘包问题?欢迎在评论区留下你的见解!


http://www.ppmy.cn/devtools/167134.html

相关文章

Redis 缓存穿透、缓存击穿与缓存雪崩详解:问题、解决方案与最佳实践

目录 引言 1. 缓存穿透 1.1 什么是缓存穿透&#xff1f; 示例&#xff1a; 1.2 缓存穿透的原因 1.3 缓存穿透的解决方案 1.3.1 缓存空对象 1.3.2 布隆过滤器&#xff08;Bloom Filter&#xff09; 1.3.3 参数校验 2. 缓存击穿 2.1 什么是缓存击穿&#xff1f; 示例&…

Docker基础命令说明

Docker基础操作命令众多&#xff0c;这些命令可以按如下方式进行分类&#xff1a; 镜像操作容器操作网络操作数据卷操作LOG查询 等方面进行分类。 一、镜像操作命令 docker images&#xff1a;用于列出本地系统中所有的 Docker 镜像。镜像就像是一个模板&#xff0c;它包含…

vue中,watch里,this为undefined的两种解决办法

提示&#xff1a;vue中&#xff0c;watch里&#xff0c;this为undefined的两种解决办法 文章目录 [TOC](文章目录) 前言一、问题二、方法1——使用function函数代替箭头函数()>{}三、方法2——使用that总结 前言 ‌‌‌‌‌尽量使用方法1——使用function函数代替箭头函数()…

TCP/IP原理详细解析

前言 TCP/IP是一种面向连接&#xff0c;可靠的传输&#xff0c;传输数据大小无限制的。通常情况下&#xff0c;系统与系统之间的http连接需要三次握手和四次挥手&#xff0c;这个执行过程会产生等待时间。这方面在日常开发时需要注意一下。 TCP/IP 是互联网的核心协议族&…

第13章贪心算法

贪心算法 局部最优求得总体最优 适用于桌上有6张纸币&#xff0c;面额为100 100 50 50 50 10&#xff0c;问怎么能拿走3张纸币&#xff0c;总面额最大&#xff1f;—拿单位价值最高的 只关注局部最优----关注拿一张的最大值拆解-----拿三次最大的纸币 不适用于桌面三件物品&am…

RabbitMQ五种消息模型

RabbitMQ 是一款基于 AMQP 协议的高性能消息中间件&#xff0c;广泛应用于分布式系统中&#xff0c;用于实现服务之间的异步通信、解耦和负载均衡。RabbitMQ 提供了五种常见的消息模型&#xff0c;每种模型都有其独特的特点和适用场景。本文将详细介绍这五种消息模型&#xff0…

在 VMware 中安装 Ubuntu 的超详细实战分享

目录 1. 安装准备VMware 软件获取Ubuntu 镜像获取 2. 创建新的虚拟机基础配置自定义硬件设置 3. Ubuntu 系统安装过程启动虚拟机正式安装 Ubuntu安装过程中常见问题 4. 安装后优化安装 VMware Tools系统更新与软件安装分辨率与显示设置 5. 常见故障及解决方案黑屏或安装卡顿网络…

接口测试工具:postman详解

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 Postman 是一款功能强大的 API 开发和测试工具&#xff0c;以下是一些高级用法的详细介绍和操作步骤。 一、环境和全局变量 环境变量允许你设置特定于环境&#…