Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.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
Java 编写多人服务器最合适的方式是什么?_Java_Multithreading_Sockets_Udp_Server - Fatal编程技术网

Java 编写多人服务器最合适的方式是什么?

Java 编写多人服务器最合适的方式是什么?,java,multithreading,sockets,udp,server,Java,Multithreading,Sockets,Udp,Server,我目前正在为一款快节奏的多人游戏编写服务器,该游戏应该以UDP运行(我认为TCP不适合处理数据包丢失,在需要及时传递数据的应用程序中,请纠正我,如果TCP更有用),该游戏不是大规模多人游戏,应该主要由玩家自己托管,可能在本地专用服务器上。虽然我非常确定客户端需要在NIO中,以避免网络问题导致的游戏延迟,但我还不知道如何编写服务器。以下是我考虑过的可能性列表: 为每个播放器使用单独的线程,每个播放器绑定一个套接字 使用一个插座在每个播放器中循环 做同样的事,但是和NIO在一起 使用一个套接字

我目前正在为一款快节奏的多人游戏编写服务器,该游戏应该以UDP运行(我认为TCP不适合处理数据包丢失,在需要及时传递数据的应用程序中,请纠正我,如果TCP更有用),该游戏不是大规模多人游戏,应该主要由玩家自己托管,可能在本地专用服务器上。虽然我非常确定客户端需要在NIO中,以避免网络问题导致的游戏延迟,但我还不知道如何编写服务器。以下是我考虑过的可能性列表:

  • 为每个播放器使用单独的线程,每个播放器绑定一个套接字
  • 使用一个插座在每个播放器中循环
    • 做同样的事,但是和NIO在一起
  • 使用一个套接字同时向所有客户端广播消息
  • 在一个单独的线程上使用一个用于接收的套接字和一个用于发送的套接字

以下哪种方法最适合在客户端数量相对较少的情况下处理时间关键型数据?(不超过16个)

TCP的开销较大,因此传输相同信息需要更高的带宽。然而,如果TCP没有到达,它确实有被重新发送的优势。如果使用UDP,请确保通过网络发送的消息是可丢失的。例如,如果您以添加和更改的形式发送移动,那么它将很快与客户端失去同步。传输时需要覆盖值

每个玩家需要一个线程来监听他们的输出,比如击键或动作,因为你必须等待每个线程上的数据,因此它将在玩家1上阻塞,直到他们做出动作,而玩家2将无法做出动作,直到玩家1做出动作


播放游戏状态可能是有意义的——但我没有这方面的经验,也没有像16个客户端的快节奏多人游戏那样对时间要求很高的经验,除非你的硬件非常糟糕,或者你做了一些异常的处理,否则无论你走哪条路,你都会表现出色。这意味着您可以以任何方式编写它,从而使编写和维护变得更简单

不过,请就您的选择说几句话:

为每个播放器使用单独的线程,每个播放器绑定一个套接字

这种方法对于数量较少的TCP套接字更有意义。如果您使用的是UDP,那么您只有一个套接字,因此没有必要这样做。但是,如果游戏需要每个客户端进行一些并行处理,那么每个客户端都有一个线程是很有用的

使用一个插座在每个播放器中循环

这可能是最简单的选择,除非你的游戏需要特别的东西。正如我前面所说的,您应该具备良好的性能。因此,如果这能让编写代码变得更容易,那就去做吧。避免

使用一个插座进行接收,另一个插座在单独的网络上进行发送 线

除非你有充分的理由这样做,否则我会避免这个想法。这可能(不必要地)使网络方面的事情复杂化,因为客户端将向端口X发送数据包,并从端口Y获得回复。这将是一个严重的问题

使用一个套接字同时向所有客户端广播消息


首先,这只能在一个方向上工作——从服务器到客户端。其次,这只会在路由器不转发广播数据包的情况下起作用。如果您对这两个限制都满意,并且发现自己正在设计一个系统,其中服务器向所有玩家(至少是同一网络中的玩家)发送一些数据包,那么这可能不是一个坏主意。就性能而言,除非您发送大量数据包,否则您可能不会注意到向每个播放机发送单独的副本和发送广播之间的区别。

有多少客户是“低数量”?@Malt不超过16是我目前工作的前提。我能问一下下一票吗?我已经尝试了尽可能多的研究工作,但我不认为这是失败的。TCP处理数据包丢失的方式到底有什么问题?NB多播与广播不同,多播套接字用于接收多播:发送多播套接字时不需要多播套接字。@EJP在丢弃的数据包到达之前不接收更多的数据包,如果数据在几毫秒内过时,则会适得其反。假设一个理论上的数据包被丢弃,你最好接收下一个数据包,然后继续前进,而不是等待旧的数据包。我相信在UDP中,与TCP不同,你可以在一个线程和套接字中接收所有通信,但是更有知识的人可能会证实这一点,@Kravaros这是正确的。与UDP不同,TCP套接字是两台不同端点的机器之间的流。好吧,看起来确实如此:尽管您需要在每一端都有一个线程来分别发送和接收,因为recieve仍然是一个阻塞方法callMultiplexed NIO使此答案的第二段不正确,你的评论就在这个上面。您可以在一个线程中完成所有操作。谢谢。硬件很糟糕,因为服务器将由玩家托管,这就是我担心的原因。你对广播包有什么建议吗?@Kravaros我也添加了一些关于广播的内容。关于硬件——再说一遍,我不知道你在设计什么游戏,但我敢打赌,一部现代手机可以轻松地为16名玩家提供服务器,只要它不做任何过于密集的事情。如果我是你,我会从一个简单的实现开始,看看它是否有效。如果没有,那么(并且只有到那时)找到瓶颈并使用上述方法修复它们。