1

I want to be able to asynchronously wait on a socket, then synchronously read from it:

for (;;) 
{
    while (data available on socket) 
    {
        read message from socket;
        process it;
    }
    do something else;
}

I need this because I want to poll a queue with messages from GUI at the same time, so the "do something else" part has a short wait().

Is this possible with Java sockets? I tried to check .available() on a DataInputStreamassociated with the socket, but

  • It seems to work only when I connect, not when I accept a connection (???)
  • I get no indication that the connection has been closed.

I tried to do it with a Selector, but it requires the socket channel to be in non-blocking mode all the time.

5 Answers 5

5

The Java non-blocking I/O package (java.nio) will allow you to do asynchronous reading from a socket via Selectors.

Check this link for some examples to get you started.

Sign up to request clarification or add additional context in comments.

1 Comment

The links are expired.
2

Why don't you use two threads (or am I misunderstanding what you want to do)?

2 Comments

I wanted to avoid splitting this into two threads, but maybe it's the best way...
You can do what you suggest, but you would make it far more complicated than just using two threads.
2

The 'available()' method of InputStream from the Socket will tell you if there is data available on the socket before you call the blocking read() method.

InputStream sockIS = sock.getInputStream();
int ba;  // Number of bytes available to read from socket
for (;;) {
    while ((ba = sockIS.available()) > 0) {
        read message from socket;
        process it;
    }
    do something else;
}

Don't call the blocking read if there is no data to read. Don't block reading more data than is available at the time.

A related method of interest (but not for your specific need) is sock.setSoTimeout(millis) this call allows you to call a sock.read(...) and have it wait for at most a specific amount of time before it throws an exception (that you would handle) or that returns data. This is useful if you want expect a prompt response but want to handle issues where a server may no longer be responding.

Another issue is that you put the one curly brackets on the wrong line, when everyone knows they belong on end of the if/while/for statement :-)

Comments

0

In sockets programming the data may come in as arbitrary chunks depending upon the interaction between the sending system, intermediate links and how your OS treats PSH flags. You'll need to put a BufferedInputStream in the middle and make use of the available() method and push back bytes until you have a complete "message" which you can then process.

The correct java solution involves making your own MessageInputStream which wraps a BufferedInputStream and provides similar available() functionality which tells the caller how many messages are immediately available for reading.

Comments

0

I'd do

public class MainClass extends WhateverSuperClass implements WhateverInterface { 
// . . .

  private Listener listener;

  public MainClass() {
    listener = new Listener(this);
  }

  public void theMethod(){
    //do something else
  }
}

public class Listener extends Thread {
  public Listener(MainClass clazz) {

    // initialize thread resources (sockets, database connections, etc)
    start();
    Thread.yield();
  }

  public void run() {
    for (;;) 
    {
      // there's no need to test if there is 
      // data available on socket, since this
      // loop runs in a separate thread

      // read message from socket;
      // clazz.process(message);
    }
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.