传出 UDP 流量是不是允许此端口上的传入流量?

Posted

技术标签:

【中文标题】传出 UDP 流量是不是允许此端口上的传入流量?【英文标题】:Does having outgoing UDP traffic allow incoming traffic on this port?传出 UDP 流量是否允许此端口上的传入流量? 【发布时间】:2013-06-12 05:42:14 【问题描述】:

我目前正在实现 UDP 服务器浏览器功能,因此玩家可以通过 php 页面(IP 和端口)找到游戏的服务器,然后从该地址请求游戏数据。 此游戏数据包括玩家数量/游戏模式等内容,还包括“真实”端口,游戏本身基于 TCP。

示例:1.1.1.1:1000 上的游戏已在该 php 页面上注册

现在我希望我的服务器浏览器向这个地址和端口发送一个 UDP 数据包,然后监听响应以获得这个游戏数据。

这不是问题,至少在没有防火墙限制的局域网中不会。

我只是好奇这是否也可以通过互联网工作,比如说:

服务器在路由器后面的 1.1.1.1:1000(用于游戏的 TCP 和用于游戏数据的 UDP)上运行。 该服务器的端口转发正确,因此客户端可以通过IP直接连接,并且可以接收和响应游戏数据请求。

IP 为 2.2.2.2 的客户端在服务器浏览器上找到了该服务器并想要获取游戏数据。他也在路由器后面,但没有转发任何端口。

现在在 TCP 中这很简单:一个 ServerSocket 可以接受传入的连接并回答它们,客户端的 Socket 可以接收回答,因为客户端自己向服务器发出了请求,对吧?

UDP 也是这样吗?就像,客户端通过 UDP 向 1.1.1.1:1000 发送一个数据包。默认情况下, new DatagramSocket() 绑定到“一些”可用的 UDP 端口,在这种情况下假设为 2000。现在我可以简单地使用 socket.getLocalPort() 并获取这个端口,构造请求包并将客户端的端口放在那里。发送后,客户端使用这个 DatagramSocket 对象来监听响应。

服务器收到这个请求包并且现在有客户端的本地端口号,所以它发送一个包含游戏数据的应答包到这个端口。 (2000)

客户端能接收到这个数据包吗?我会说是的,因为客户端使用这个 UDP 端口向它接收应答的 IP 发送一个数据包,所以客户端的防火墙应该让那个端口的“应答”通过。

并且:接收数据包的 DatagramPacket.getPort() 是否包含发送方使用的 UDP 端口? 示例:从端口 2000 发送的数据包在端口 1000 上接收 -> getPort() 返回 1000 还是 2000 ?

感谢您的回答:)

【问题讨论】:

【参考方案1】:

这里没有 TCP 和 UDP 的区别。在这两种情况下(客户端连接到服务器,路由器将端口转发到服务器)都有 NAT:网络地址转换。

如果我们以 nat 后面的客户端和服务器为例:

客户端发送数据包:srcip1, srcport1 -> dstip1, dstport1; 客户端的 nat 路由器翻译:srcip2, srcport2 -> dstip1, dstport1; 服务器的 nat 路由器翻译:srcip2, srcport2 -> dstip2, dstport2; 服务器收到数据包。

当服务器发回一个数据包时会发生相反的情况。但是原理是一样的。再说一遍,TCP、UDP,这里没有区别。

唯一的区别是路由器跟踪这些地址/端口映射有多“难”。 TCP 比 UDP 更容易(因为 TCP 是面向会话的)。但请注意,对于 ICMP 也必须这样做(这对于 ping 是必需的,但对于网络不可达消息和其他消息也是如此;ping 是 echo-r​​equest out,echo-r​​eply in)。

(顺便说一句,这可能属于服务器故障?)

【讨论】:

另请注意,我使用“发送数据包”一词。一个套接字可能是“服务器套接字”或任何东西这一事实根本不重要:)【参考方案2】:

通常是的。 NAT 通常允许传入响应到它刚刚看到传出数据包的 UDP 源-目标对。但是,超时各不相同。

【讨论】:

谢谢!就我而言,超时应该不是问题:)

以上是关于传出 UDP 流量是不是允许此端口上的传入流量?的主要内容,如果未能解决你的问题,请参考以下文章

拦截**传出** HTTP(S) 流量

配置 nginx 以允许自定义端口上的 HTTPS 流量

通过 *** 从 GKE Pod 传出的流量

如何检测 SSTP 流量?

传出流量 AWS 的公共 IP 地址

网络理论的最大流量问题