我正在用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。
发布于 2016-09-22 22:40:40
通常,不能将不属于本地计算机的IP bind()。但是,根据IP_TRANSPARENT文档:
IP_TRANSPARENT (自从Linux2.6.24之后) 设置此布尔选项可在此套接字上进行透明代理。此套接字选项允许调用应用程序绑定到非本地IP地址,并以外部地址作为本地端点作为客户端和服务器进行操作。注意:这要求路由的设置方式是通过TProxy框(即承载使用IP_TRANSPARENT套接字选项的应用程序的系统)路由到外部地址的数据包。启用此套接字选项需要超级用户特权( CAP_NET_ADMIN功能)。 带有iptables目标的TProxy重定向还要求在重定向套接字上设置此选项。
您是否在您的网络上配置了必要的代理以方便IP_TRANSPARENT
让我们暂时忽略IP_TRANSPARENT,假装它不存在,因为它不是常用的。
127.0.0.1是IPv4环回地址。如果将服务器绑定到此,则只有连接到IPv4的本地127.0.0.1客户端才能进行连接。
0.0.0.0是一个IPv4通配符地址。如果将服务器绑定到此,套接字将侦听所有本地IPv4地址。本地计算机或网络上的任何客户端都可以连接到属于服务器机器的任何IPv4地址。
192.168.1.1是一个特定的IPv4地址。如果将服务器绑定到此位置,则套接字将只侦听该IPv4地址。本地计算机或网络上的任何客户端只能连接到该IPv4地址。
如果客户端和服务器位于同一台计算机上,则客户端可以连接到服务器绑定到的任何本地IP。
如果您的客户端和服务器不在同一台计算机上,则如果服务器绑定到可由该网络访问的IP,则客户端可以连接到该服务器。这意味着绑定到0.0.0.0或192.168.1.1,然后连接到192.168.1.1。
如果您的客户端和服务器不在同一网络上,则只有当服务器位于具有公共IP的路由器后面时,客户端才能连接到服务器。必须将服务器绑定到路由器可访问的本地网络IP,并且必须将路由器配置为将其公共IP上的给定端口上的入站连接转发到服务器的内部IP。这意味着将服务器绑定到0.0.0.0或192.168.1.1,将连接转发到服务器的内部IP,然后连接到路由器的公共IP。
https://stackoverflow.com/questions/39649705
复制相似问题