1

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

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

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

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

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

一台服务器在路由器后面的 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 ?

感谢您的回答:)

4

2 回答 2

0

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

于 2013-06-15T20:47:46.763 回答
0

这里 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)。

(作为旁注,也许这属于服务器故障?)

于 2013-06-15T21:00:12.267 回答