boost::asio 中的 NAT 打孔

问题描述

我正在尝试使用 boost::asio 实现 NAT 打孔。据我了解,NAT 打孔是这样工作的(UDP/TCP):

  1. 客户端 A 绑定到一个端口并连接到服务器 S,客户端 B 也这样做。
  2. 当 S 收到请求并匹配时,它将 A 的 ip 和端口发送给 B,B 发送给 A。
  3. A 和 B 收到对方的 ip 和端口,现在他们从同一个端口向对方发送消息并形成连接(因为他们期待回复?)

所以在 boost::asio 中,我能够实现步骤 1-2,但是由于两个客户端都没有进行端口转发,如果我尝试从一个客户端连接到另一个客户端,它只会给我这样的错误“客户端主动拒绝连接”或“客户端无响应”(令人惊讶的是,两个客户端即使使用相同的功能也有不同的错误)。

如果没有成功的 asio::async_writeasync_connect,我似乎无法运行任何 asio::tcp::socket::connect。当然,当目标端口没有被转发时,这两个连接函数都会给我错误

那么在这种情况下我如何实现 NAT 打孔,我是不是在 boost::asio 中遗漏了什么?任何帮助表示赞赏!谢谢。

解决方法

基于“客户端主动拒绝连接”错误,我假设您正在尝试 TCP 连接。 UDP 和 TCP 打孔的工作原理存在根本区别。

3. A 和 B 收到对方的 ip 和端口,现在他们从同一个端口互相发送消息并形成连接(因为他们期待回复?)

这不是 TCP 打孔的工作原理。由于 TCP 是点对点的,因此在步骤 3 中您必须预测 A 或 B 的下一个传入端口,并且 A 或 B 需要尝试使用预测的端口建立新连接另一边。显然有许多不同的 NAT 实现,并且并不总是能够可靠地预测端口分配,尤其是在运营商级 NAT 的情况下。有关详细信息,请参阅 TCP hole punching。作为 TCP 打孔的替代方法,请查看 UPnP 以添加端口转发。