基于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代码。
测试流程
- 在
soft40051-simple-container1容器中启动Server:java Server - 在
ntu-vm-soft40051容器中启动Client:java Client - 客户端应该能收到服务器发送的消息,服务器端会打印客户端连接日志。
备注:内容来源于stack exchange,提问作者Yash Gadgil
相关产品推荐
相关产品推荐

