1

我正在编写涉及服务器和许多客户端的简单应用程序。我必须使用 DataGramSocket。应用程序是通过控制台简单地交换消息,就像聊天一样。但是 in.readLine() 和 ds.receive() 中的两个操作都是阻塞的,将它们放在单独的线程中并没有帮助,因为阻塞 i/o 也会阻塞线程。任何人都可以告诉我没有nio我怎么能做到这一点

4

3 回答 3

1

如果您有专门用于通过网络发送或接收数据的线程,那么线程阻塞将不是问题,因为只有该专用线程会被阻塞。

然后,让我们考虑此解决方案对应用程序中线程数的影响:

  • 如果每个服务器只有几个客户端,那么每个客户端有 2 个 I/O 线程不是问题。
  • 如果每台服务器有很多客户端,那么您应该接受这样一个事实,即他们的一些请求不会立即处理,而是只有工作线程才可用。您可以尝试生成与客户端一样多的 I/O 线程,但单个 JVM 实例可以拥有的线程数存在限制。确切的数字取决于您的 JVM 可用的堆大小以及您的架构是 32 位还是 64 位,请参见此处

如果您对处理大量客户的一般任务感兴趣,这里是关于这个问题的经典网络论文。

于 2010-10-09T20:50:54.157 回答
0

首先,您应该使用 java.nio 来获得非阻塞 I/O。假设你不能,出于某种原因......

您可以使用 DatagramSocket 和工作队列(例如 java.util.concurrent.ThreadPoolExecutor)轻松地让服务器处理来自多个客户端的数据。

这个想法是你有一个读取套接字的接收器线程,每个数据报都被接收,包装在一个“ReceivedDatagram”对象中并放到工作队列中。工作队列有一个线程池,其线程出列并处理每个数据包;如果数据包需要响应,则线程在阻塞之前发送响应(阻塞)以使另一个 ReceivedDatagram 出列。

要异步发送数据,您只需在代表要发送的 DatagramPacket 的工作队列上放置一个“SendDatagram”对象。

请注意,您将使用 Datagram.receive(DatagramPacket) 和 Datagram.send(DatagramPacket)。

于 2010-10-09T20:44:50.870 回答
0

您可以通过在单独的线程中执行阻塞操作来做到这一点,使用手动生成的线程或更好的线程池 (http://www.ibm.com/developerworks/library/j-jtp0730.html)

于 2010-10-09T20:45:15.540 回答