java 如何在java中使接受的套接字非阻塞

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1698654/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 17:39:24  来源:igfitidea点击:

How to make an accepted socket non-blocking in java

javasocketsnonblocking

提问by Benaiah

I'm accepting a connection from a client and then passing that connected socket off to another object, however, that socket needs to be non-blocking. I'm trying to use getChannel().configureBlocking(false)but that does not seem to be working. It needs to be non-blocking because this the method below is called every 100ms. Is there some other way that I should be making this non-blocking? Thanks for any help!

我正在接受来自客户端的连接,然后将该连接的套接字传递给另一个对象,但是,该套接字需要是非阻塞的。我正在尝试使用,getChannel().configureBlocking(false)但这似乎不起作用。它需要是非阻塞的,因为下面的方法每 100 毫秒调用一次。有没有其他方法可以使这个非阻塞?谢谢你的帮助!

public void checkForClients() {
  DataOutputStream out;
  DataInputStream in;
  Socket connection;
  InetAddress tempIP;
  String IP;

  try {
     connection = serverSocket.accept();
     connection.getChannel().configureBlocking(false);

     System.err.println("after connection made");

     in = new DataInputStream(connection.getInputStream());
     out = new DataOutputStream(connection.getOutputStream());
     tempIP = connection.getInetAddress();
     IP = tempIP.toString();

     System.err.println("after ip string");

     // create a new user ex nihilo
     connectedUsers.add(new ConnectedUser(IP, null, connection, in, out));


     System.err.println("after add user");
  } catch (SocketTimeoutException e) {
     System.err.println("accept timeout - continuing execution");
  } catch (IOException e) {
     System.err.println("socket accept failed");
  }
}

回答by cletus

Two things:

两件事情:

  1. Why aren't you using a ServerSocketif you're listening for connections?
  2. If you want to accept multiple clients you want to use a loop.
  1. ServerSocket如果您正在侦听连接,为什么不使用 a ?
  2. 如果要接受多个客户端,则要使用循环。

The basic structure of a multi-client server is:

多客户端服务器的基本结构是:

while (true) {
  // accept connections
  // spawn thread to deal with that connection
}

If the issue is blocking on the accept()call, well that's what accept()does: it blocks waiting for a connection. If that's an issue I suggest you have a separate thread to accept connections.

如果问题是accept()呼叫阻塞,那么就是accept()这样:它阻塞等待连接。如果这是一个问题,我建议您有一个单独的线程来接受连接。

See Writing the Server Side of a Socket.

请参阅编写套接字的服务器端

回答by simon

I would expect your code to block on the accept call, never getting to the configureBlocking call.

我希望你的代码在接受调用时阻塞,永远不会进入 configureBlocking 调用。

I typically spin off a separate thread for each socket connection, and let it block until a connection is actually made/accepted This allows the main thread to continue unblocked while it is waiting for client connections.

我通常为每个套接字连接分离一个单独的线程,并让它阻塞直到实际建立/接受连接这允许主线程在等待客户端连接时继续畅通无阻。

回答by Seth

If you're looking for non-blocking sokets, my suggestion is to use Selectors and ServerSocketChannels with the NIO package.

如果您正在寻找非阻塞 soket,我的建议是将 Selectors 和 ServerSocketChannels 与 NIO 包一起使用。

http://java.sun.com/j2se/1.4.2/docs/guide/nio/

http://java.sun.com/j2se/1.4.2/docs/guide/nio/

回答by Schildmeijer

One approach is to use an I/O loop (event loop) in a single threaded environment. Take a look at Deft web serverfor inspiration. (Especially the start() method in IOLoop)

一种方法是在单线程环境中使用 I/O 循环(事件循环)。看一看Deft Web 服务器以获得灵感。(尤其是IOLoop 中的 start() 方法)

回答by Yishai

If the typical blocking socket doesn't give you the availability you need (a connection every 100ms does seem tight). You should look at a non-blocking socket. Here is a tutorial. You can also look at Apache MINAto make this easier.

如果典型的阻塞套接字不能为您提供所需的可用性(每 100 毫秒连接一次似乎很紧张)。您应该查看非阻塞套接字。这是一个教程。您还可以查看 Apache MINA简化此操作。