我正在尝试使用mingw工具链实现使用Windows套接字的TCP打孔。我认为这个过程是正确的,但 hole 似乎没有。我使用this作为参考。
我认为代码中没有任何问题:
10060
)我遗失了什么?
编辑:在进程资源管理器的帮助下,我看到其中一个客户端设法与对等方建立连接。但是同伴似乎并没有考虑要建立联系。
这是我用Wireshark捕获的内容。为示例,服务器 S 和客户端 A 位于同一台PC上。服务器 S 侦听重定向到该PC的特定端口(8060
)。 B 仍尝试连接正确的IP,因为它看到 S 发送的 A 的公开地址为localhost
,因此使用 S 的公共IP代替。 (我已经用占位符替换了公共IP)
编辑2 :我认为混淆是由于传入和传出的连接请求数据都在同一端口上传输。这似乎弄乱了连接状态,因为我们不知道哪个套接字将从端口获取数据。如果我引用msdn:
SO_REUSEADDR
套接字选项允许套接字强制绑定到a 另一个套接字使用的端口。第二个套接字调用setsockopt optname参数设置为SO_REUSEADDR
和optval参数集 在调用与之相同的端口上的bind之前,将布尔值设置为TRUE
原装插座。 第二个套接字成功绑定后,即可 绑定到该端口的所有套接字的行为是不确定的。
但TCP Hole Punching技术需要在同一个端口上进行交谈才能打开漏洞!
答案 0 :(得分:12)
开始2个主题:
一个线程尝试使用S
发送的信息连接到B的路由器 另一个线程在连接到S
时用于连接到路由器的同一端口上等待传入连接
你不能用两个线程来做这个,因为它只是一个操作。每个进行出站连接的TCP连接也在等待传入连接。您只需调用'connect',并且您发送出站SYN以建立连接并等待入站SYN建立连接。
但是,您可能需要关闭与服务器的连接。当您已经从同一端口建立了连接时,您的平台可能不允许您从端口建立TCP连接。因此,就像启动TCP打孔一样,关闭与服务器的连接。将新的TCP套接字绑定到同一端口,然后调用connect
。
答案 1 :(得分:1)
遍历NAT路由器的一个简单解决方案是使您的流量遵循NAT已经具有转发算法的协议,例如FTP。
答案 2 :(得分:0)
使用Wireshark检查tcp连接请求(3路Handhsake过程)是否正常。
确保您的Listener线程正在使用select()对描述符进行解复用。
sockPeerConect(用于连接其他对等体的套接字)是Listener Thread中的FD_SET()。
确保您正在检查
int Listener Thread()
{
while(true)
{
FD_SET(sockPeerConn);
FD_SET(sockServerConn);
FD_SET(nConnectedSock );
if (FD_ISSET(sockPeerConect)
{
/// and calling accept() in side the
nConnectedSock = accept( ....);
}
if (FD_ISSET(sockServerConn)
{
/// receive data from Server
recv(sockServerConn );
}
if (FD_ISSET(nConnectedSock )
{
/// Receive data from Other Peer
recv(nConnectedSock );
}
}
}
5.确保您同时启动对等连接A到B和B到A. 6.在连接到服务器和Peer之前启动监听器线程,并使用单个侦听器线程接收服务器和客户端。
答案 3 :(得分:-3)
并非每个路由器都支持tcp打孔,请查看以下详细说明的文件:
Peer-to-Peer Communication Across Network Address Translators