MST

星途 面试题库

面试题:Java中Socket跨平台通信时如何处理粘包和拆包问题

在Java使用Socket进行跨平台通信场景下,网络传输中经常会出现粘包和拆包的情况。请描述你所知道的处理粘包和拆包问题的方法,并给出简单的代码示例来展示如何在Java的Socket编程中实现其中一种方法。
39.8万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

处理粘包和拆包问题的方法

  1. 定长数据包:发送端发送固定长度的数据包,接收端每次按固定长度读取数据。这种方式简单,但可能造成空间浪费。
  2. 包尾添加特殊分隔符:在每个数据包的末尾添加特殊的分隔符,接收端根据分隔符来识别数据包的结束。
  3. 包头加上包体长度:在包头中定义一个字段来表示包体的长度,接收端先读取包头获取包体长度,再根据长度读取包体内容。

使用“包头加上包体长度”方法的代码示例

发送端代码

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public class SocketSender {
    public static void main(String[] args) {
        try (Socket socket = new Socket("127.0.0.1", 8888);
             DataOutputStream dos = new DataOutputStream(socket.getOutputStream())) {
            String message = "Hello, Server!";
            // 发送包体长度
            dos.writeInt(message.length());
            // 发送包体
            dos.writeUTF(message);
            dos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

接收端代码

import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketReceiver {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(8888);
             Socket socket = serverSocket.accept();
             DataInputStream dis = new DataInputStream(socket.getInputStream())) {
            // 读取包体长度
            int length = dis.readInt();
            // 读取包体
            String message = dis.readUTF();
            System.out.println("Received message: " + message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}