Search code examples
javasocketstelnetapache-commons-net

inputstream.read() timeout seconds are counting even when the thread is not currently in the method


I'm using TelnetClient.class from Apache Commons Net 3.3 jar. My problem is that the behavior of the method setSoTimeout() is not what is expected. This method, as far as i know, simply calls the one with the same name but in the Socket.class setting the read() timeout. This is a sample code (IOManager is just a class i made for I/O operations):

telnet = new TelnetClient();
telnet.connect("localhost", 2020);
telnet.setSoTimeout(10000);

manager = new IOManager(telnet.getInputStream(), telnet.getOutputStream());
while (true) {
  System.out.println(manager.readBuffer());
  Thread.sleep(10000);
  manager.sendMessage("Peanut Butter Jelly");
}

And this is the code of the method i use to read in IOManager class (reader is a BufferedReader with the telnet inputstream which has the soTimeout enabled):

public String readBuffer() throws IOException {
        StringBuilder message = new StringBuilder();
        int len;
        char[] chars = new char[1024];
        do {
            if ((len = reader.read(chars)) != -1) {
                message.append(chars, 0, len);
                Thread.sleep(30);
            } else {
                throw new IOException("Stream closed");
            }
        } while (reader.ready());
        return message.toString();
    }

My problem is: even when im not calling the read() in the moment the timeout seconds are counting! All i want is to attempt to read data for 10 seconds but when i read something and then i wait 10 seconds and write, when i attempt again to read BOOM! java.net.SocketTimeoutException: Read timed out.

The timeout is expiring instantly! The server side then throw this: java.net.SocketException: Software caused connection abort: recv failed

The processes i work with do a lot of things before reading again, even waiting more than 20 minutes before sending a command again. The application must restart when it doesn't get an answer in the specified timeout. If i delete the Thread.sleep() it reads and sends correctly, as long as the client could not read data in 10 seconds (normal)

I work a lot with Server/Client programs and Sockets. This is only happening when using the TelnetClient. What could be the problem? Why this behavior? If i can't get it to work i think im going to use Callabe and Future interfaces but that is another Thread just to read (ouch, im actually making multiple connections to that Telnet Server).

Thanks for reading.


Solution

  • I ran into this problem and solved it by turning off the reader thread in TelnetClient:

    telnet = new TelnetClient();
    telnet.setReaderThread(false); // This prevents the timeout bug
    telnet.connect("localhost", 2020);
    telnet.setSoTimeout(10000);