2016-09-22 114 views
0

我正在写一个简单的服务器/客户端程序C.我试图打开一个端口上可以从任何地方访问的IP。目前,我的服务器不工作,但127.0.0.1(本地机器)和0.0.0.0(我不知道)。我已经指定了IP_TRANSPARENT选项,除了客户端外,其他所有内容仍然在connect失败。连接()到外部IP不工作

服务器:

// 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。

+0

服务器的IP地址是192.168.1.1吗? – immibis

回答

3

通常情况下,您不能将bind()转换为不属于本地计算机的IP。然而,每IP_TRANSPARENT文档:

IP_TRANSPARENT(因为Linux 2.6.24)
设置这个布尔选项启用此套接字上透明代理。 这个套接字选项允许调用应用程序绑定到一个非本地IP地址,并作为一个客户端和一个服务器使用外地址作为本地端点。注意:这要求路由的设置方式是通过TProxy框(即托管使用IP_TRANSPARENT套接字选项的应用程序的系统)路由到外地址的数据包。启用此套接字选项需要超级用户权限(CAP_NET_ADMIN功能)。

使用iptables TPROXY目标进行TProxy重定向还要求在重定向的套接字上设置此选项。

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

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

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

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

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

如果您的客户端和服务器位于同一台计算机上,则客户端可以连接到服务器绑定的任何本地IP。

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

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

+0

我可以绑定到'0.0.0.0',然后在同一台机器上连接到'192.168.1.1'吗?因为它看起来不像是在工作。 –

+0

@MDXF如果'192.168.1.1'属于本地机器,那么是的,当本地服务器绑定到'0.0.0.0'时,本地客户端应该能够连接到它。 –

+0

其实,当我在主机'0.0.0.0'端口'4001'上运行服务器,并在主机'192.168.1.1'和端口'4001'上运行客户端时,我在连接时出错。 192.168.1.1是否属于网络路由器? –