面试突击:什么是粘包和半包?怎么解决?

粘包和半包问题是数据传输中比较常见的问题,所谓的粘包问题是指数据在传输时,在一条消息中读取到了另一条消息的部分数据,这种现象就叫做粘包。比如发送了两条消息,分别为“ABC”和“DEF”,那么正常情况下接收端也应该收到两条消息“ABC”和“DEF”,但接收端却收到的是“ABCD”,像这种情况就叫做粘包,如下图所示:

面试突击:什么是粘包和半包?怎么解决?插图亿华云

半包问题是指接收端只收到了部分数据,而非完整的数据的情况就叫做半包。比如发送了一条消息是“ABC”,而接收端却收到的是“AB”和“C”两条信息,这种情况就叫做半包,如下图所示:

面试突击:什么是粘包和半包?怎么解决?插图1亿华云

PS:大部分情况下我们都把粘包问题和半包问题看成同一个问题,所以下文就用“粘包”问题来替代“粘包”和“半包”问题。

1.为什么会有粘包问题?

粘包问题发生在 TCP/IP 协议中,因为 TCP 是面向连接的传输协议,它是以“流”的形式传输数据的,而“流”数据是没有明确的开始和结尾边界的,所以就会出现粘包问题。

2.粘包问题代码演示

接下来我们用代码来演示一下粘包和半包问题,为了演示的直观性,我会设置两个角色:

服务器端用来接收消息;客户端用来发送一段固定的消息。

然后通过打印服务器端接收到的信息来观察粘包问题。服务器端代码实现如下:

/**

* 服务器端(只负责接收消息)

*/

class ServSocket {

// 字节数组的长度

private static final int BYTE_LENGTH = 20;

public static void main(String[] args) throws IOException {

// 创建 Socket 服务器

ServerSocket serverSocket = new ServerSocket(8888);

// 获取客户端连接

Socket clientSocket = serverSocket.accept();

// 得到客户端发送的流对象

try (InputStream inputStream = clientSocket.getInputStream()) {

while (true) {

// 循环获取客户端发送的信息

byte[] bytes = new byte[BYTE_LENGTH];

// 读取客户端发送的信息

int count = inputStream.read(bytes, 0, BYTE_LENGTH);

if (count

THE END
Copyright © 2024 亿华云