我正在尝试在主机和Docker容器之间传递一条简单的消息。
我首先使用主机网络驱动程序创建了docker容器:
docker run -t -d --network host --name cfalcon ubuntu
接下来,我进入了容器:
docker exec -it cfalcon
我使用以下命令将主机IP标识为192.168.0.109,并将容器IP标识为172.17.0.1。
hostname -I
我在〜/ Documents / tcp_server.c中用以下代码在容器中创建了一个文件:
#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;
}
回到主机,我决定使用以下代码在〜/ Documents / tcp_client.c中创建一个新文件:
#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;
}
不幸的是,我没有收到“ Its-a me,a-Mario!”,而是“与远程套接字建立连接时出错”。
我相信我可以使用各自的IP和相同的端口号完美地将两者链接在一起,但是我似乎没有。如果您对我的困境有任何指导,请告诉我。
编辑:更新!我在容器上安装了Netcat,并在主机和容器之间建立了连接。
主持人:$ nc -l 9001
容器:$ nc localhost 9001
在以下提示中从容器发送的任何消息都会到达我的主机,这告诉我这仅仅是我的代码错误。
答案 0 :(得分:0)
在最低级别,您的服务器代码 bind (2)到192.168.0.9,但是您的客户端代码 connect (2)到172.17.0.1。服务器将仅接受与其绑定到的单个地址的连接。如果您使用的是Docker主机网络,则从网络的角度来看,服务器进程与主机上运行的任何其他进程都没有区别,而172.17.0.1也可能到达主机,因为它的地址并不完全相同,您的连接将被拒绝。
如果服务器在Docker容器中运行,并且客户端直接在同一主机上运行:
--net host
启动容器。请使用适当的-p
选项将其启动,以将容器端口映射到某个主机端口。例如-p 9001:9001
。如果客户端在同一主机上的其他容器中运行:
docker create network something
。您不需要任何其他参数,但是您确实需要创建网络。docker run
使用两个容器时,请以与您先前创建的网络相匹配的--net something
和有用的--name
来启动它们。sockaddr
。请注意,这些路径均不涉及查找容器专用IP地址(在普通的“连接到该主机名”路径中作为低级详细信息除外)。这会定期更改(无论何时删除和重新创建容器),都无法从脱离主机访问,甚至在某些Docker设置中也无法从主机控制台访问。永远不需要进行查找。
还要注意,这两个路径都不涉及docker exec
。这是一个有用的调试工具,但通常不是核心容器工作流程的一部分。 (如果您发现自己“ docker run
是一个容器,然后立即docker exec
”,通常应该更改容器启动顺序以执行docker exec
本身的所有操作。)