简体   繁体   English

Docker中如何让客户端和服务器监听同一个端口

[英]How to get client and server to listen to the same port in Docker

This Docker network contains two Java files, a client and a server.这个 Docker 网络包含两个 Java 文件,一个客户端和一个服务器。 The goal is to get the client to send a message to the server.目标是让客户端向服务器发送消息。

I have hard-coded the server to listen to the port 7892 .我已经硬编码服务器来监听端口7892 So if I run the server locally outside Docker, it will listen to localhost:7892 .因此,如果我在 Docker 之外本地运行服务器,它将监听localhost:7892 Likewise, I have hard-coded the client to send its message to port 7892 on a passed IP address, and I pass localhost if running locally.同样,我对客户端进行了硬编码,以将其消息发送到传递的 IP 地址上的端口 7892,如果在本地运行,我传递localhost

Once I containerize the server and client in Docker, it's a struggle to get the client to send its message to the server.一旦我将服务器和客户端容器化到 Docker 中,就很难让客户端将其消息发送到服务器。 The client will attempt to send its message, but I'm not sure where it's sending it to.客户端将尝试发送其消息,但我不确定它会将其发送到哪里。 The server is listening to some port, but I'm not sure why the two are not connecting to each other.服务器正在侦听某个端口,但我不确定为什么两者没有相互连接。

docker-compose.yml: docker-compose.yml:

version: '3.9'

services:
  server:
    build:
      context: ./
      dockerfile: Dockerfile-project1
    image: project1:latest
    container_name: server
    working_dir: /parallelcomputing
    networks:
      - project1network
    ports:
      - 7892 # this is what I've put in my TCPClient and TCPServer
    command:
      - /bin/bash
      - -c
      - |
        echo "Initialize client...done!"
        cd project1
        java -cp ../socket_programming/target/socket_programming-1.0-SNAPSHOT.jar edu.rit.cs.socket.TCPServer
        tail -f /dev/null

  client:
    image: project1:latest
    container_name: client
    depends_on:
      - server
    working_dir: /parallelcomputing
    networks:
      - project1network
    command:
      - /bin/bash
      - -c
      - |
        echo "Initialize server...done!"
        cd project1
        java -cp ../socket_programming/target/socket_programming-1.0-SNAPSHOT.jar edu.rit.cs.socket.TCPClient affr.csv host.docker.internal
        tail -f /dev/null

networks:
  project1network:

When I run docker ps I can see当我运行docker ps时,我可以看到

0f9857535e5a   project1:latest   "/bin/bash -c 'echo …"   2 minutes ago   Up 2 minutes                             client
71b499a3c71f   project1:latest   "/bin/bash -c 'echo …"   2 minutes ago   Up 2 minutes   0.0.0.0:55000->7892/tcp   server

It appears the server is listening to port 7892 on the docker network localhost (which, according to my understanding, is host.docker.internal ).看来服务器正在侦听 docker 网络 localhost 上的端口 7892(据我了解,它是host.docker.internal )。

In my docker-compose.yml, I try to tell the client to send its message to port 7892 on the docker network local host as well, but it's not working.在我的 docker-compose.yml 中,我尝试告诉客户端将其消息发送到 docker 网络本地主机上的端口 7892,但它不起作用。

client    | IO:Connection refused (Connection refused)

I have tried multiple other port configurations, searched through the networking documentation, but I'm not sure how to get the two to connect?我尝试了多种其他端口配置,搜索了网络文档,但我不确定如何让两者连接?

Likewise, I have hard-coded the client to send its message to port 7892 on a passed IP address, and I pass localhost if running locally.同样,我对客户端进行了硬编码,以将其消息发送到传递的 IP 地址上的端口 7892,如果在本地运行,我传递 localhost。
.... The client will attempt to send its message, but I'm not sure where it's sending it to... ....客户端将尝试发送它的消息,但我不确定它发送到哪里......

Since you're not providing target IP or hostname, your client implementation is sending request to itself (same docker container).由于您没有提供目标 IP 或主机名,因此您的客户端实现正在向自身发送请求(相同的 docker 容器)。

I'd recommend reading this official Docker Networking in Compose documentation.我建议阅读Compose 文档中的官方 Docker Networking文档。

For example, suppose your app is in a directory called myapp, and your docker-compose.yml looks like this:例如,假设您的应用位于名为 myapp 的目录中,并且您的 docker-compose.yml 如下所示:

 version: "3.9" services: web: build: . ports: - "8000:8000" db: image: postgres ports: - "8001:5432"

Each container can now look up the hostname web or db and get back the appropriate container's IP address.每个容器现在可以查找主机名 web 或 db 并取回相应容器的 IP 地址。 For example, web's application code could connect to the URL postgres://db:5432 and start using the Postgres database.例如,web 的应用程序代码可以连接到 URL postgres://db:5432 并开始使用 Postgres 数据库。

Or you can either specify server's hostname and you can use that hostname from client implementation.或者,您可以指定服务器的主机名,也可以使用客户端实现中的主机名。

version: '3'
services:
  dns:
    hostname: 'server0001'

Then your client application should send request to server0001:7892然后您的客户端应用程序应该向server0001:7892发送请求

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM