gpt4 book ai didi

connect() 到外部 IP 不工作

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:06:31 26 4
gpt4 key购买 nike

我正在用 C 编写一个简单的服务器/客户端程序。我正在尝试在 IP 上打开一个可以从任何地方访问的端口。目前,除了 127.0.0.1(本地机器)和 0.0.0.0(我不知道),我的服务器不工作。我已经指定了 IP_TRANSPARENT 选项,但客户端在 connect 时仍然失败。

服务器:

// definitions, everything
struct addrinfo hints, *res;

hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;

getaddrinfo("192.168.1.1","4001",&hints,&res);

sockfd = socket(res->ai_family,res->ai_socktype,res->ai_protocol);

setsockopt(sockfd,IPPROTO_IP,IP_TRANSPARENT,(void*)&sockopt,sizeof(sockopt));

bind(sockfd,res->ai_addr,res->ai_addrlen);
listen(sockfd,0);

addr_size = sizeof(ext_addr);
extfd = accept(sockfd,(struct sockaddr *)&ext_addr,&addr_size);

write(extfd,"Success",7);
// cleanup

客户:

// definitions, everything
struct sockaddr_in serv_addr;

sockfd = socket(AF_INET,SOCK_STREAM,0);
setsockopt(sockfd,IPPROTO_IP,IP_TRANSPARENT,(void*)&sockopt,sizeof(sockopt));

serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(4001);

inet_pton(AF_INET,"192.168.1.1",&serv_addr.sin_addr);

connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)); // fails here
read(sockfd,rcvBuf,sizeof(rcvBuf)-1);

// clean up

我的问题是什么?为了方便起见,我把错误检查去掉了。服务器运行良好,我确信这一点。客户端在 127.0.0.1 上运行良好。

最佳答案

通常,您不能bind() 到不属于本地机器的IP。但是,根据 IP_TRANSPARENT 文档:

IP_TRANSPARENT (since Linux 2.6.24)
Setting this boolean option enables transparent proxying on this socket. This socket option allows the calling application to bind to a nonlocal IP address and operate both as a client and a server with the foreign address as the local endpoint. NOTE: this requires that routing be set up in a way that packets going to the foreign address are routed through the TProxy box (i.e., the system hosting the application that employs the IP_TRANSPARENT socket option). Enabling this socket option requires superuser privileges (the CAP_NET_ADMIN capability).

TProxy redirection with the iptables TPROXY target also requires that this option be set on the redirected socket.

您是否在网络上配置了必要的代理以促进IP_TRANSPARENT

让我们暂时忽略 IP_TRANSPARENT,假装它不存在,因为它不常用。

127.0.0.1 是 IPv4 环回地址。如果将服务器绑定(bind)到此,则只有连接到 127.0.0.1 的本地 IPv4 客户端才能连接。

0.0.0.0 是一个 IPv4 通配符地址。如果将服务器绑定(bind)到此,套接字将监听所有本地 IPv4 地址。本地计算机或网络上的任何客户端都可以连接到属于服务器计算机的任何 IPv4 地址。

192.168.1.1 是一个特定的 IPv4 地址。如果将服务器绑定(bind)到此,则套接字将仅监听该 IPv4 地址。本地机器或网络上的任何客户端只能连接到该 IPv4 地址。

如果您的客户端和服务器在同一台机器上,则客户端可以连接到服务器绑定(bind)的任何本地 IP。

如果您的客户端和服务器不在同一台机器上,但在同一网络上,如果服务器绑定(bind)到该网络可访问的 IP,则客户端可以连接到服务器。这意味着绑定(bind)到 0.0.0.0192.168.1.1,然后连接到 192.168.1.1

如果您的客户端和服务器不在同一网络上,则只有当服务器位于具有公共(public) IP 的路由器后面时,客户端才能连接到服务器。服务器必须绑定(bind)到路由器可访问的本地网络 IP,并且路由器必须配置为将其公共(public) IP 上给定端口上的入站连接转发到服务器的内部 IP。这意味着将服务器绑定(bind)到 0.0.0.0192.168.1.1,将连接转发到服务器的内部 IP,然后连接到路由器的公共(public) IP。

关于connect() 到外部 IP 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39649705/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com