Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets 如果服务器从其他端口响应,则客户端不会从服务器接收UDP数据报 环境:_Sockets_Networking_Network Programming_Udp_Nat - Fatal编程技术网

Sockets 如果服务器从其他端口响应,则客户端不会从服务器接收UDP数据报 环境:

Sockets 如果服务器从其他端口响应,则客户端不会从服务器接收UDP数据报 环境:,sockets,networking,network-programming,udp,nat,Sockets,Networking,Network Programming,Udp,Nat,客户端-NAT后面的Windows桌面,运行UDP客户端应用程序 服务器-具有公共IP的Ubuntu服务器,运行一个UDP服务器应用程序,该应用程序需要端口6000上的数据包 ClientPrivate/Public-客户端的私有/公共IP ServerPrivate/Public-服务器的私有/公共IP 案例1: 客户端在ClientPrivate:777上打开UDP套接字,并向ServerPublic:6000发送数据报 服务器从ClientPublic:777接收数据报,并从ServerP

客户端-NAT后面的Windows桌面,运行UDP客户端应用程序

服务器-具有公共IP的Ubuntu服务器,运行一个UDP服务器应用程序,该应用程序需要端口6000上的数据包

ClientPrivate/Public-客户端的私有/公共IP

ServerPrivate/Public-服务器的私有/公共IP

案例1: 客户端在ClientPrivate:777上打开UDP套接字,并向ServerPublic:6000发送数据报 服务器从ClientPublic:777接收数据报,并从ServerPrivate:6000向ClientPublic:777发送响应 客户收到回复,一切正常 服务器上的WireShark输出: 475 88.xxx.xxx.90->10.0.0.5 UDP 777→ 6000 476 10.0.0.5->88.xxx.xxx.90 UDP 6000→ 777

客户端上的WireShark输出: 152 192.168.2.85 104.40.xxx.250 UDP 777→ 6000 153 104.40.xxx.250 192.168.2.85 UDP 6000→ 777

案例2: 客户端在ClientPrivate:777上打开UDP套接字,并向ServerPublic:6000发送数据报 服务器从ClientPublic:777接收数据报 服务器在ServerPrivate:46666上打开一个新套接字,并向ClientPublic:777发送数据报 客户端没有收到数据报 服务器上的WireShark输出: 475 88.xxx.xxx.90->10.0.0.5 UDP 777→ 6000 476 10.0.0.5->88.xxx.xxx.90 UDP 46666→ 777

客户端上的WireShark输出: 152 192.168.2.85 104.40.xxx.250 UDP 777→ 6000

问题:
为什么在案例1中客户端接收到数据报而在案例2中没有接收到数据报?

我认为这是由于客户端NAT造成的。当客户端向服务器发送公共IP时,NAT路由器在其内部连接表中创建一个条目,如192.168.2.85[777]=>104.40.xxx.250[6000]

因此,当响应从104.40.xxx.250[6000]返回时,NAT将找到匹配的条目,并将响应返回到客户端机器。该条目是它如何知道将数据包发送到客户端网络中的哪台机器的。然而,当响应从104.40.xx.250[46666]返回时,它与表中的任何条目都不匹配,因此它将丢弃该数据包

这就是NAT的工作方式。考虑一下,如果你的NAT后面还有另一台机器,也和同一个服务器交谈,比如192.1682.86[ 777 ]=104.40。XXX。250 [ 6000 ]。我想你会发现你的NAT路由器实际上把源端口改成了777以外的端口。否则,它将如何正确地将响应路由回正确的机器。一般来说,对于NAT,如果来自路由器的传入数据包与其表中的条目不匹配,或者您已经配置了端口转发规则,则数据包将被丢弃


端口转发允许您打开内部计算机,以便外部世界进行一般访问。但是如果没有这一点,您真的不希望任何随机IP地址/端口对能够向客户端计算机发送数据报。

服务器专用网络是否以任何方式连接到客户端公用网络?如果没有,那么您希望如何在两个网络之间发送数据包?服务器中的sendto调用没有失败吗?没有失败。客户端只是不接收数据报。这些网络不仅通过互联网连接。我怎么期望。。?我不知道。。这就是为什么我描述了这些案例。如果在这两种情况下它都不起作用,我不会问,但在第一种情况下它确实起作用。为了使数据包能够从一个主机传送到另一个主机,主机的网络之间需要有某种连接,尽管这种连接是间接的。如果没有这样的连接,或者没有路由告诉数据包应该发送到哪里,那么这根本不可能。如果服务器专用网络确实是专用的,并且没有与客户机公用网络的物理连接,那么数据包就无法传输。它将如何通过不存在的连接?在第一种情况下,两个公共网络明显相连,这就是它工作的原因。听起来很合理,但我仍然不明白。为什么在第一种情况下网络明显连接,而在第二种情况下网络没有连接?这里真正的问题是为什么服务器从不同的端口响应?不要浪费港口。使用与接收请求相同的套接字进行响应。问题实际上是由NAT引起的。首先需要将数据包从客户端发送到服务器,这样NAT就可以创建一个适当的映射条目,将响应数据包路由回客户端。如果没有从客户端到服务器的传出数据包,而服务器只是将数据包发送到客户端,那么这些数据包将被丢弃,因为NAT盒上还没有正确的映射。