C ++ UDP套接字在收到来自客户端的第一个数据包后无法从服务器发送回客户端

C++ UDP Socket not working to send back from server to client after receiving first packets from client

用 C++ 编写一个 UDP 客户端-服务器应用程序(在过去 15 年中用多种语言做过很多次),但不知何故这个程序无法正常工作。

我目前无法 post 实际代码或最小可复制应用程序,但如果有人可以通过屏幕共享帮助快速解决此问题,我愿意支付实时帮助费用。

我认为这是 C++ 套接字的特殊性以及我在此特定应用程序中使用它们的方式非常复杂。

基本上问题是从服务器发送到客户端的数据包没有被客户端接收,只有当所述客户端在一个单独的 nat 上时。 当两者都在同一个本地网络中并使用他们的本地 IP 时,一切都按预期进行。

这是我正在做的事情:

  1. 客户端 sendto(...) 使用特定服务器主机和端口 12345 通过 UDP 向服务器发送数据包(并不停地发送这些数据)
  2. 在另一个线程上,客户端 bind(...) 在端口 12345 和“0.0.0.0”上并尝试循环 poll()recvfrom()(轮询总是 returns 0这里当客户端在一个单独的 nat)
  3. 服务器 bind() 在端口 12345 和“0.0.0.0” 然后 poll()recvfrom() 循环
  4. 从客户端接收到第一条UDP消息后,它启动一个线程用于发送 UDP 消息返回到客户端 在新的套接字 上,使用 sockaddr_in 它从 recvfrom() 中获取并传递给 sendto() 命令。

结果:服务器完美地接收来自所有客户端的所有消息,并将所有消息发送回所有客户端,但任何不在同一 NAT 上的客户端将永远不会收到任何消息(poll() 总是 returns 0).

据我了解,当客户端通过特定的远程端口(在本例中为 12345)向服务器发送 UDP 消息时,它会在其 NAT 中打一个洞,以便它可以从该端口上的远程服务器...

我测试了五种不同的客户端网络配置:

  1. 与服务器的本地网络,使用本地 IP 地址 (WORKS)
  2. 当客户端使用 VPN 时与服务器的本地网络因此通过远程 NAT(不工作)
  3. 与服务器的本地网络,但客户端正在使用 WAN ip 地址连接到服务器(不起作用)
  4. 来自朋友连接的实际远程网络中的客户端,在路由器后面(不起作用)
  5. 客户端正在使用我的 phone 创建的 wifi 热点(不工作)

对于上述所有测试,服务器正确接收来自客户端的所有通信。

我还尝试将 sendto() 的端口强制设置为 12345,而不是使用 recvfrom() 中设置的 sockaddr_in,同样的问题。

我做错了什么吗?

如果您想提供帮助但需要查看实际代码,我可以通过屏幕共享实时做到这一点,我会支付帮助费用。

谢谢。

另外,如果有人能给我指出一个很棒的网站,在那里我可以付费获得非常快速的帮助,请告诉我,我什至懒得搜索 google 因为我真的需要人们的实际建议谁尝试过这些服务,而不是试图敲诈我的广告...

只允许原始接收方套接字回复客户端,因为在NAT 中打开端口的是客户端请求。因此,要么在服务器中使用相同的套接字来接收和回复,要么获取第二个服务器套接字绑定到的端口并通过原始服务器端口将其与初始消息一起传输,以便 A 可以发送给它并打孔.

当套接字是全双工通信对象时创建两个半双工套接字看起来很奇怪,我会选择第一个选项。