You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Java Socket编程实现多Docker容器间的连接与数据共享

基于Java Socket编程实现多Docker容器间的连接与数据共享

看起来你已经搞定了Docker容器的网络连通(能ping通就迈出了关键一步!),但在Java Socket的实现上踩了几个容易忽略的小坑,我来帮你一步步调整:

先说说你当前代码里的核心问题

  • 误用系统预留端口:你把Socket服务绑在了22端口,这是SSH的默认服务端口,会和容器里的SSH服务冲突,而且也不符合Socket服务的最佳实践,得换一个自定义端口(比如8888、9999这类未被占用的端口)。
  • 容器连接方式不够稳定:用容器ID作为连接地址虽然能通,但容器重启后ID会变,不如直接用容器名称更可靠(你的容器名分别是ntu-vm-soft40051和soft40051-simple-container1)。
  • 缺少实际的数据收发逻辑:你的代码框架已经搭好了,但核心的读写数据部分是空的,得补全。

调整后的完整实现步骤

先贴一下你的容器信息,方便后续参考:

5071de43f576   22/tcp, 0.0.0.0:3390->3389/tcp   ntu-vm-soft40051
a6d4bc5dadf0   0.0.0.0:4848->22/tcp             soft40051-simple-container1

1. 修改服务器端代码(运行在soft40051-simple-container1容器)

把端口换成自定义的8888,同时补全数据发送逻辑:

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

public class Server {
    // 改用自定义的Socket服务端口,避开系统预留端口
    private static final int PORT = 8888;

    public static void main(String[] args) throws IOException {
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("服务器已启动,监听端口:" + PORT);
            while (true) {
                // 等待客户端连接
                Socket socket = serverSocket.accept();
                System.out.println("新客户端已连接:" + socket.getInetAddress());

                // 向客户端发送数据
                OutputStream output = socket.getOutputStream();
                PrintWriter writer = new PrintWriter(output, true);
                writer.println("Hello from server!");
                writer.println("当前服务器时间:" + new Date().toString());
                writer.println("容器名:soft40051-simple-container1");
            }
        } catch (IOException ex) {
            System.out.println("服务器异常:" + ex.getMessage());
            ex.printStackTrace();
        }
    }
}

2. 修改客户端代码(运行在ntu-vm-soft40051容器)

用容器名称作为连接地址,端口和服务器端保持一致,补全数据接收逻辑:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {
    public static void main(String[] args) throws IOException {
        // 用容器名称作为连接地址,同一Docker网络下可以直接解析
        String serverHost = "soft40051-simple-container1";
        int serverPort = 8888;

        try (Socket socket = new Socket(serverHost, serverPort)) {
            System.out.println("已连接到服务器");

            // 读取服务器发送的数据
            InputStream input = socket.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(input));

            String line;
            System.out.println("收到服务器消息:\n");
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (UnknownHostException ex) {
            System.out.println("找不到服务器:" + ex.getMessage());
        } catch (IOException ex) {
            System.out.println("I/O错误:" + ex.getMessage());
        }
    }
}

3. Docker容器运行注意事项

  • 确保两个容器在同一个自定义Docker网络中(如果是默认桥接网络,可能需要额外配置,但你已经能ping通,应该没问题)。
  • 不需要为这个8888端口做宿主机映射(除非你需要从宿主机访问这个Socket服务),容器间在同一网络下可以直接通过内部端口通信。
  • 把编译好的.class文件分别放到对应的容器里,或者直接在容器内编译运行Java代码。

测试流程

  1. 在soft40051-simple-container1容器中启动Server:java Server
  2. 在ntu-vm-soft40051容器中启动Client:java Client
  3. 客户端应该能收到服务器发送的消息,服务器端会打印客户端连接日志。

备注:内容来源于stack exchange,提问作者Yash Gadgil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 07:04:08