传出 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-request out,echo-reply in)。
(顺便说一句,这可能属于服务器故障?)
【讨论】:
另请注意,我使用“发送数据包”一词。一个套接字可能是“服务器套接字”或任何东西这一事实根本不重要:)【参考方案2】:通常是的。 NAT 通常允许传入响应到它刚刚看到传出数据包的 UDP 源-目标对。但是,超时各不相同。
【讨论】:
谢谢!就我而言,超时应该不是问题:)以上是关于传出 UDP 流量是不是允许此端口上的传入流量?的主要内容,如果未能解决你的问题,请参考以下文章