TCP外网反连接内网失败,请求指教!
服务器端:
sockaddr_in acc_addr;
int addSize = sizeof(sockaddr);
SOCKET s = accept(sock, (sockaddr*)&acc_addr, &addSize);
以上是接收客户端发起的连接请求——成功;
然后服务器端又通过以下方式向客户端发起连接请求——失败。
sockaddr_in addr2;
addr2.sin_family = acc_addr.sin_family;
addr2. sin_port = acc_addr.sin_port; //服务器端得到的客户端外网端口
addr2. sin_addr.s_addr = acc_addr.sin_addr; //服务器端得到的客户端外网IP
connect(sock2, (sockaddr *)&addr2, sizeof(sockaddr));
客户端:
int res = ms.Connect(sock, serverIP, port);
sockaddr_in in_addr;
int nAddrLen = sizeof(sockaddr);
int res = getsockname(sock, (sockaddr *)&in_addr, &nAddrLen);
unsigned short port1 = ntohs(in_addr.sin_port);
AfxBeginThread((AFX_THREADPROC)TCP_ThreadListen, (LPVOID)port1);//在客户端监听port1端口,监听成功
[解决办法]
如果客户端是一台直接暴露在外网上的计算机,具有公网IP地址,那么直接连接就可以了;
如果客户端是在躲在路由器之后的内网计算机,IP地址是内网的私有地址,就必须通过路由器的NAT才能连接到外网上,这样外网上的主机如果要访问这台计算机,就要穿透路由器的NAT。
可以参考这几个链接:
http://www.cnblogs.com/epan/articles/98379.html
http://zh.wikipedia.org/wiki/NAT%E7%A9%BF%E9%80%8F
http://michankong.blog.51cto.com/1464983/761270
http://blog.csdn.net/hairetz/article/details/4101918
[解决办法]
我认识有不少人搞过这个nat打洞,从未听说过tcp能成功打洞,就算是udp成功率也没办法达到100%的能穿透。
nat为了保证安全很多包是直接拒绝掉的,外网的tcp请求是直接过滤掉的。
你应该看看nat原理性的东西