Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make an accepted socket non-blocking in java

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!

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");
  }
}
like image 452
Benaiah Avatar asked Nov 09 '09 01:11

Benaiah


People also ask

How do I make a socket non-blocking?

A blocking accept() call does not return to your program until a client connects to your socket program. Change a socket to nonblocking mode using the ioctl() call that specifies command FIONBIO and a fullword (four byte) argument with a nonzero binary value.

Is socket accept blocking Java?

Socket programs in Java can be made to work in both blocking and non-blocking mode. In blocking socket mode, a system call event halts the execution until an appropriate reply has been received.

Is socket accept blocking?

If no pending connections are present on the queue, and the socket is not marked as nonblocking, accept() blocks the caller until a connection is present. If the socket is marked nonblocking and no pending connections are present on the queue, accept() fails with the error EAGAIN or EWOULDBLOCK.


2 Answers

Two things:

  1. Why aren't you using a ServerSocket if you're listening for connections?
  2. If you want to accept multiple clients you want to use a loop.

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.

See Writing the Server Side of a Socket.

like image 73
cletus Avatar answered Oct 05 '22 23:10

cletus


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

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.

like image 29
simon Avatar answered Oct 05 '22 21:10

simon