繁体   English   中英

服务器UDP和端口绑定

[英]Server UDP and port binding

我正在用Java编写游戏,但网络体系结构存在问题。

我决定我将UDP数据包。 我只是刚开始,但是我面临的问题是,服务器必须从完全相同的IP /端口向客户端(位于使用NAT的路由器后面)的客户端做出响应,因为客户端连接了该服务器。

例如,我在路由器后面有客户端A。 客户端A具有IP(本地)192.168.8.100,它从端口1234连接服务器B。服务器位于11.11.11.11:2345。

当客户端A连接到服务器B时,它使用192.168.8.100:1234,但路由器将其转换为(例如)22.22.22.22:6789。

现在,当服务器要将数据包发送到该客户端时,它必须来自11.11.11.11:2345。 我想从另一个端口(如11.11.11.11:2222)发送数据,但这似乎不起作用,至少不适用于我的路由器。

我想使用不同的端口,因为我想拥有两个线程,一个用于侦听,另一个用于发送数据,并且每个线程都有自己的DatagramSocket。 但是,正如我所说,一旦客户端A在端口2345上连接到服务器,我就无法从端口2222发送数据。

有人知道如何处理吗? 我是用Java编写的,但这并不是语言特定的问题。

更新

@Perception发表评论后,我对他的评论还有其他疑问:

好的,因此,如果我正确理解这一点,如果我的服务器托管着1000个游戏,每个游戏都有2个玩家,则所有发送/接收都必须通过相同的DatagramSocket完成。

据我了解,DatagramSocket是线程安全的,所以我想我可以有一个线程在做:

datagramSocket.receive();

同时第二个线程正在做

datagramSocket.send(.....);

正确?

另外,两个线程可以通过相同的DatagramSocket同时发送数据吗? 是否以任何方式序列化发送,这意味着第二个send()仅在上一个send()完成或同时发送数据之后才开始?

gorann,我不确定我是否理解正确,但是听起来您正在尝试控制服务器与客户端进行通信的端口。 有充分的理由,无法控制此情况。

这是TCP和UDP之间棘手的区别之一。

当启动新的TCP会话时,服务器端对accept()的调用会为您提供一个新的套接字,并且操作系统会为您处理各种会话的复用。 使用UDP,您需要自己处理多路复用。 但是您需要以与NAT和其他防火墙一起使用的方式进行操作。

NAT的工作方式是,当它看到传出数据包时,会创建一个临时规则,允许数据包沿着同一端口对返回。 从客户端尚未发送到的端口返回的数据可能会被阻止。

这给您两个选择:

  1. 您可以通过单个端口进行所有通信。 这不是一个坏选择,仅表示您需要一种方法来标识客户端会话并将其路由到适当的线程。

  2. 您可以创建一个单独的端口,并指示客户端改为发送到该端口。 让服务器监听固定端口。 客户端向此处发送消息,然后服务器设置一个新的会话端口,并使用服务器的侦听端口将该号码发送回客户端。 然后,客户端将消息发送到会话端口,这将导致NAT打开该端口并允许返回流量。 现在,客户端和服务器线程具有自己的专用端口对。

选项1需要做更多的工作,因为它需要在线程之间交换数据,但是可以更好地扩展。 选项1更容易且CPU效率更高,因为每个会话线程都可以独立,但是可用端口数量有限。

无论哪种方式,我都建议您让客户端在每个数据包中都包含一个半唯一的会话ID,以便服务器不仅仅具有客户端地址和端口号来验证谁属于每个会话。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM