windows - TCP 打洞

标签 windows tcp network-protocols winsock2 hole-punching

我正在尝试使用 mingw 工具链通过 Windows 套接字实现 TCP 打洞。我认为这个过程是正确的,但似乎并没有采取。我用了this作为引用。

  1. AB 连接到服务器S
  2. S 发送给AB的路由器IP+它用来连接到S的端口
  3. SB
  4. 做同样的事情
  5. A 启动 2 个线程:
    • 一个线程尝试使用 S 发送的信息连接到 B 的路由器
    • 另一个线程在连接到 S
    • 时正在用于连接其路由器的同一端口上等待传入连接
  6. B 做同样的事情

我认为代码没有问题,因为:

  • AB 确实互相获取了 ip 和端口以供使用
  • 当他们联系服务器时,他们都在监听他们用来连接路由器的端口
  • 它们都连接到正确的 ip 和端口但超时(代码错误 10060)

我错过了什么?

编辑: 在进程浏览器的帮助下,我看到其中一个客户端设法与对等方建立了连接。但是对等方似乎没有考虑建立连接。

这是我使用 Wireshark 捕获的内容。为了示例,服务器 S 和客户端 A 在同一台 PC 上。服务器 S 监听重定向到该 PC 的特定端口 (8060)。 B 仍然尝试连接正确的 IP,因为它看到 S 发送的 A 的公共(public)地址是 localhost 并因此改用 S 的公共(public) IP。 (我已经用占位符替换了公共(public) IP)

wireshark

编辑 2:我认为造成混淆的原因是传入和传出连接请求数据都在同一端口上传输。这似乎弄乱了连接状态,因为我们不知道哪个套接字将从端口获取数据。如果我引用 msdn:

The SO_REUSEADDR socket option allows a socket to forcibly bind to a port in use by another socket. The second socket calls setsockopt with the optname parameter set to SO_REUSEADDR and the optval parameter set to a boolean value of TRUE before calling bind on the same port as the original socket. Once the second socket has successfully bound, the behavior for all sockets bound to that port is indeterminate.

但是 TCP 打洞技术需要在同一个端口上通信才能打开孔!

最佳答案

A start 2 threads:
One thread tries connecting to B's router with the info sent by S
The other thread is waiting for an incoming connection on the same port used to connect to its router when it connected to S

你不能用两个线程来做这个,因为它只是一个操作。每个建立出站连接的 TCP 连接也在等待传入连接。您只需调用“连接”,即可发送出站 SYN 以建立连接并等待入站 SYN 建立连接。

但是,您可能需要关闭与服务器的连接。当您已经从同一端口建立连接时,您的平台可能不允许您从该端口建立 TCP 连接。因此,就像您开始 TCP 打洞一样,关闭与服务器的连接。将新的 TCP 套接字绑定(bind)到同一端口,并调用 connect

关于windows - TCP 打洞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8819118/

相关文章:

windows - 使用批处理重新排列数字

java - java中的POST与android中的POST不同吗?

c++ - TCP recvfrom() 不存储 'from'

go - Golang中的TCP固定大小消息成帧方法

usb - 罗技统一接收器协议(protocol)?

Python ctypes 和没有足够的参数(缺少 4 个字节)

c# - 尽管主机中的映射已被注释,但 localhost 仍然有效

tcp - HAProxy 关闭长期存在的 TCP 连接,忽略 TCP keepalive

java - 记录之间的数据交换非常慢

windows - 有没有一种简单的方法可以从嵌套的批处理脚本中捕获错误代码 (%errorlevel%)?