主机到Docker容器远程套接字故障

主机到Docker容器远程套接字故障,docker,sockets,networking,containers,port,Docker,Sockets,Networking,Containers,Port,我试图在主机和docker容器之间传递一条简单的消息 我首先使用主机网络驱动程序创建docker容器: docker run-t-d——网络主机——名称cfalcon ubuntu 接下来,我进入了容器: docker exec-it cfalcon 我使用:标识主机IP为192.168.0.109,容器IP为172.17.0.1 hostname-I 我在容器中的~/Documents/tcp_server.c中创建了一个文件,代码如下: TCP_SERVER.C #包括 #包括 #包括 #包

我试图在主机和docker容器之间传递一条简单的消息

我首先使用主机网络驱动程序创建docker容器:
docker run-t-d——网络主机——名称cfalcon ubuntu

接下来,我进入了容器:
docker exec-it cfalcon

我使用:
标识主机IP为192.168.0.109,容器IP为172.17.0.1
hostname-I

我在容器中的~/Documents/tcp_server.c中创建了一个文件,代码如下:

TCP_SERVER.C
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[]){
字符地址[]=“192.168.0.109”;
//创建服务器套接字
int-server_-socket;
服务器\u套接字=套接字(AF\u INET,SOCK\u STREAM,0);
//定义服务器地址
服务器地址中的结构sockaddr\u;
服务器地址.sin\u family=AF\u INET;
//指定端口,以确保安全
服务器地址sin端口=htons(9001);
服务器地址sin\u addr.s\u addr=inet\u addr(地址);
//将套接字绑定到指定的IP 192.168.0.109
绑定(server_socket,(struct sockaddr*)和server_地址,sizeof(server_地址));
//函数的作用是:开始侦听连接
侦听(服务器\u套接字,1);
//接受连接的能力
int客户机接口;
客户端\u套接字=接受(服务器\u套接字,NULL,NULL);
char server_message[256]=“这是一个我,一个马里奥!”;
//使用Send()发送消息
发送(客户端\u套接字,服务器\u消息,sizeof(服务器\u消息),0);
关闭(服务器_套接字);
返回0;
}
回到主机,我决定在~/Documents/tcp_client.c创建一个新文件,代码如下:

TCP_CLIENT.C
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[]){
字符地址[]=“172.17.0.1”;
//创建套接字
int网络接口;
//套接字(套接字的域(通常是一个常量)、TCP套接字、协议)
网络套接字=套接字(网络,套接字流,0);
//为套接字指定地址(地址族与Socket()的参数之一相同)
服务器地址中的结构sockaddr\u;
服务器地址.sin\u family=AF\u INET;
//指定端口,以确保安全
服务器地址sin端口=htons(9001);
服务器地址sin\u addr.s\u addr=inet\u addr(地址);
//返回用于错误处理的整数
int connection_status=connect(网络套接字,(结构sockaddr*)和服务器地址,sizeof(服务器地址));
//错误处理
如果(连接状态==-1){
printf(“连接到远程套接字时出错。\n\n”);
}
//如果我们发送数据,我们将从recv中的服务器接收响应
字符服务器_响应[256];
recv(网络套接字和服务器响应),sizeof(服务器响应),0;
//打印服务器的响应
printf(“服务器响应:%s\n”,服务器\u响应);
//避免数据泄露
关闭(网络插座);
返回0;
}
不幸的是,我没有收到“Its-ame,a-Mario!”,而是收到“连接到远程套接字时出错”

我相信我使用各自的IP和相同的端口号将两者完美地连接起来,但似乎我没有。如果你对我的困境有任何指导,请告诉我

编辑:更新!我在容器上安装了Netcat,并在主机和容器之间建立了连接。
主机:
$nc-l9001

容器:
$nc localhost 9001


以下提示中从容器发送的任何消息都会到达我的主机,这告诉我这只是我的代码错误。

在最低级别,您的服务器代码绑定到192.168.0.9,但您的客户端代码连接到172.17.0.1。服务器将只接受到其绑定到的单个地址的连接。如果您使用的是Docker主机网络,则从网络的角度来看,服务器进程与主机上运行的任何其他进程都是无法区分的,而172.17.0.1可能也会到达主机,因为它的地址不完全相同,因此您的连接将被拒绝

如果服务器在Docker容器中运行,而客户端直接在同一主机上运行:

  • (2)绑定到0.0.0.0。(绑定到127.0.0.1将使进程无法从容器外部访问;容器私有IP地址不可预测。)
  • 不要用
    --net host
    启动容器。请使用适当的
    -p
    选项将容器端口映射到某个主机端口;例如,
    -p 9001:9001
  • 从同一主机上的非Docker运行的客户端,连接到127.0.0.1端口9001。从其他主机(Docker或其他主机)使用第一个主机的名称
  • 如果客户端在同一主机上的不同容器中运行:

  • (2)绑定到0.0.0.0
  • docker创建网络内容
    。您不需要任何附加参数,但需要创建网络
  • 当您
    docker运行这两个容器时,请使用与您先前创建的网络相匹配的
    --net something
    和一个有用的
    --name
    来启动它们
  • 在客户端,使用getaddrinfo(3)查找服务器的容器名称;然后(2)连接到该
    sockaddr
  • 请注意,这两个路径都不涉及查找容器专用IP地址(普通“连接到此主机名”路径中的低级详细信息除外)。这是例行更改(无论何时删除和重新创建容器),无法从非主机访问,甚至在某些Docker设置中无法从主机控制台访问。没有必要去查这个

    还请注意
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #include <sys/socket.h>
    #include <sys/types.h>
    
    #include <arpa/inet.h>
    #include <netinet/in.h>
    
    int main(int argc, char* argv[]) {
    
        char address[] = "192.168.0.109";
        // Creating Server Socket
        int server_socket;
        server_socket = socket(AF_INET, SOCK_STREAM, 0);
    
        // Defining Server Address
        struct sockaddr_in server_address;
        server_address.sin_family = AF_INET;
        // Specify the port, 9001 seems safe
        server_address.sin_port = htons(9001);
        server_address.sin_addr.s_addr = inet_addr(address);
    
        // Binding our Socket to our Specified IP, 192.168.0.109
        bind(server_socket, (struct sockaddr *) &server_address, sizeof(server_address));
    
        // Listen() Function Begins Listening for a Connection
        listen(server_socket, 1);
    
        // Ability to Accept Connections
        int client_socket;
        client_socket = accept(server_socket, NULL, NULL);
    
        char server_message[256] = "Its-a me, a-mario!";
    
        // Send a message with send()
        send(client_socket, server_message, sizeof(server_message), 0);
    
        close(server_socket);
    
        return 0;
    }
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #include <sys/socket.h>
    #include <sys/types.h>
    
    #include <arpa/inet.h>
    #include <netinet/in.h>
    
    int main(int argc, char* argv[]) {
        char address[] = "172.17.0.1";
        // Creating a Socket
        int network_socket;
        // socket(domain of socket (generally AF_INET, a constant), TCP socket, protocol)
        network_socket = socket(AF_INET, SOCK_STREAM, 0);
    
        // Specifying an Address for the Socket (Address family is same as parameter one of socket())
        struct sockaddr_in server_address;
        server_address.sin_family = AF_INET;
    
        // Specify the port, 9001 seems safe
        server_address.sin_port = htons(9001);
        server_address.sin_addr.s_addr = inet_addr(address);
    
        // Returns an integer for error handling
        int connection_status = connect(network_socket, (struct sockaddr *) &server_address, sizeof(server_address));
        // Error Handling
        if (connection_status == -1) {
            printf("There was an error making a connection to the remote socket.\n\n");
        }
    
        // If we send data, we receive a response from the server in recv
        char server_response[256];
        recv(network_socket, &server_response, sizeof(server_response), 0);
    
        // Printing the Server's Response
        printf("The server responded with: %s\n", server_response);
    
        // Avoiding data leaks
        close(network_socket);
    
        return 0;
    }