我正在使用mingw工具链和windows socket尝试实现TCP打洞。我认为过程是正确的,但洞似乎没有打通。我参考了这个。
- A 和 B 连接到服务器 S
- S 向 A 发送 B 的路由器 IP + 它用于连接到S的端口
- S 对 B 也做同样的事情
- A 开始了两个线程:
- 一个线程尝试使用由 S 发送的信息连接到 B 的路由器
- 另一个线程在连接到S时使用相同的端口等待传入连接
- B 做同样的事情
我认为代码没有问题,因为:
- A 和 B 都获得了对方的 IP 和要使用的端口
- 当他们联系服务器时,他们都在监听连接到它们的路由器的端口
- 他们都连接到正确的 IP 和端口,但会超时 (错误代码
10060
)
我是否有遗漏的东西?
编辑:使用Process Explorer的帮助,我看到其中一个客户端设法与对等方建立了连接。但是,对等方似乎没有考虑到这个连接已经建立。
以下是我用 Wireshark 抓取的内容。为了举例说明,服务器 S 和客户端 A 在同一台PC上。服务器 S 监听一个特定端口(8060
)并重定向到该PC。由于S发送的A的公共地址是localhost
,因此B仍然尝试在正确的IP上连接,并因此使用S的公共IP。(我已经用占位符替换了公共IP)
编辑2:我认为混淆的原因是传入和传出的连接请求数据都传输在同一端口上。这似乎搞乱了连接状态,因为我们不知道哪个套接字会从端口获取数据。如果我引用 MSDN:
SO_REUSEADDR
套接字选项允许套接字强制绑定到另一个套接字使用的端口。第二个套接字在在调用与原始套接字相同端口上的 bind之前,将 setsockopt 的 optname 参数设置为SO_REUSEADDR
,optval 参数设置为布尔值TRUE
。一旦第二个套接字成功绑定,所有绑定到该端口的套接字的行为都是不确定的。
但在 TCP 穿洞技术中需要通过同一端口交流以“打开洞口”!