Docker 容器无法连接到我的 java 侦听主机的应用程序,但它能够连接到其他应用程序

Docker container is not able to connect to my java application listening on host but it is able to connect to others applications

我在 Windows 10 19042 上使用 WSL2。这是我的设置,适用于 netcatnpx http-serverpython -m SimpleHTTPServer 等其他应用程序。

在 Java 8 和 11 上测试。以下屏幕截图来自此版本。

java --version

openjdk 11.0.10 2021-01-19
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.10+9)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.10+9, mixed mode)

步骤

java ./Server.java
docker-compose up -d
ssh root@localhost -p 2222 # password is root
apt update && apt install -y netcat
nc -v docker-host 8080 # or nc -v host.docker.internal 8080

截图

docker-compose.yml

version: "3.8"
services:
  docker-host:
    image: qoomon/docker-host
    cap_add: ["NET_ADMIN", "NET_RAW"]
    restart: on-failure
    environment:
      - PORTS=8080

  ssh:
    image: rastasheep/ubuntu-sshd
    ports:
      - "2222:22"

Server.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class Server implements AutoCloseable {
  private final ServerSocket server;

  public Server(String host, int port, int backlogConnectionQueueLength)
      throws UnknownHostException, IOException {
    InetAddress inetAddress = InetAddress.getByName(host);
    System.out.println("inetAddress: " + inetAddress);
    server = new ServerSocket(port, backlogConnectionQueueLength, inetAddress);
    System.out.println(Thread.currentThread() + " Created Server");
  }

  public static void main(String[] args) {
    try (Server server = new Server("localhost", 8080, 50)) {
      server.start();
    } catch (IOException e) {
      System.out.println(e);
    }
  }

  public void start() {
    System.out.println(Thread.currentThread() + " Server Ready: " + server);
    while (true) {
      acceptAndHandleClient(server);
    }
  }

  private void acceptAndHandleClient(ServerSocket server) {
    System.out.println(Thread.currentThread() + " Waiting for Incoming connections...");
    try (Socket clientSocket = server.accept()) {
      handleNewClient(clientSocket);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  private void handleNewClient(Socket clientSocket) throws IOException {
    System.out.println(Thread.currentThread() + " Received Connection from " + clientSocket);
    BufferedReader is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    PrintStream os = new PrintStream(clientSocket.getOutputStream());
    // echo that data back to the client, except for QUIT.
    String line = null;
    while ((line = is.readLine()) != null) {
      System.out.println(Thread.currentThread() + " Server Got => " + line);
      if (line.equalsIgnoreCase("QUIT")) break;
      else {
        System.out.println(Thread.currentThread() + " Server echoing line back => " + line);
        os.println("Response: " + line);
        os.flush();
      }
    }
    System.out.println(Thread.currentThread() + " Server Closing Connection by Sending => Ok");
    os.println("Ok");
    os.flush();
    is.close();
    os.close();
  }

  public void close() throws IOException {
    server.close();
  }
}

又是作者post,我知道怎么解决了。 java 应用程序默认在 IPv6 上 运行,在 IPv4 上应该是 运行。所以你只需要 运行 应用程序:

java -Djava.net.preferIPv4Stack=true ./Server.java