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