4

I have a device which implements a Telnet server and I am writing java code to communicate with it. The current implementation "works" and by that I mean it will for a while then hangs, sometimes immediately, sometimes after an hour or anywhere in between. I am not ruling out the possibility that it is the device itself, however, long running sessions with putty seem to have no trouble, so I am working under the assumption that it is my java code.

I'll lay out my code first then describe the problem in more detail:

The connection is handled by an object, EthernetTelnetConnection() which uses Apache Commons TelnetClient() under the hood.

public EthernetTelnetConnection(String host, int port) throws IOException {
    mTelnet = new TelnetClient();
    mTelnet.connect(host, port);

    mOut = mTelnet.getOutputStream();
    mIn = mTelnet.getInputStream();
}

These streams are converted into buffered streams via:

mReadStream = new BufferedInputStream(mConnection.getInputStream());
mWriteStream = new BufferedOutputStream(mConnection.getOutputStream());

And can be acquired via:

public BufferedInputStream getInputStream() {
    return mReadStream;
}

public BufferedOutputStream getOutputStream() {
    return mWriteStream;
}

So after creating the connection, I start trying to parse the stream. This occurs in a dedicated thread who's only purpose in life is to execute this one method:

public void detectMessages() throws IOException {
    final BufferedInputStream in = mTekdaqc.getInputStream();
    StringBuilder builder = new StringBuilder();
    int data;
    final Scanner scan = new Scanner(in, "UTF-8").useDelimiter(Character.toString((char) AASCIIMessage.RECORD_SEPARATOR_CHAR));
    while (scan.hasNext()) {
        onMessageDetected(scan.next());
    }

    /*while ((data = in.read()) != -1) {
    if (data == AASCIIMessage.RECORD_SEPARATOR_CHAR) {
        onMessageDetected(builder.toString());
            builder = new StringBuilder();
        } else {
            builder.append((char) data);
        }
    }*/
}

And AASCIIMessage.RECORD_SEPARATOR_CHAR is defined as:

public static final int RECORD_SEPARATOR_CHAR = 0x1E;

There are some extra variables there from the commented section at the bottom which was my previous attempt. BOTH METHODS EXHIBIT THE SAME PROBLEM which is: onMessageDetected() eventually gets called with tens of thousands of strings which are empty. Usually if I let things run, eventually things continue as usual for a while then this problem begins again. So I am trying to figure out what is causing both the scanner and the simple while loop/read cycle to detect message delimiters. When capturing the wireshark traffic between the device and putty I can confirm that it is not sending these separators, though it is sending keep alive packets.

UPDATE

It was suggested to me that this might be a problem where the Apache TelnetClient is interpreting a sequence of bytes as a terminal command which Putty is not. I am not sure what terminal implementation the device implements as I did not create that code and it is not documented. I took a look at putty and it does not indicate a terminal type in the Telnet configuration window.

UPDATE 2

I hooked up System.out to the spy stream of the TelnetClient instance and examine the output in a hex editor and discovered that the stream is actually seeing repeating RS (0x1E) characters. Sniffing the traffic with a Putty Telnet connection I do not see this, so is there some sort of configuration that is incorrect with the TelnetClient class and my device?

Jared
  • 1,449
  • 2
  • 19
  • 40
  • if you could help us re-create this issue? – Mrunal Gosar Sep 09 '14 at 03:41
  • @MrunalGosar I'm not sure what you are asking. To reproduce exactly you would need the device and access to code which isn't available for release yet. I can certainly include more if people feel it is relevant or necessary but so far it has not been indicated. – Jared Sep 09 '14 at 03:45
  • I was hoping if you could provide some small scenario to mimick your problem? – Mrunal Gosar Sep 09 '14 at 04:00
  • @MrunalGosar To be honest I'm not even sure of what is going on, much less how to produce it outside of the scenario I have before me. – Jared Sep 09 '14 at 04:21
  • Are you sure output stream of your telnet process is UTF-8 ? – Adam Sep 09 '14 at 04:24
  • @Adam Fairly certain. The Telnet server source is C code executed on an ARM processor and I have made no attempt to change the execution encoding with the compiler, so it should be the UTF-8 default. All of my serial output and putty work fine treating the streams as UTF-8. – Jared Sep 09 '14 at 04:28
  • The reason I suggest that might be an issue if you're see characters won't which weren't seen in the traffic bytes (your UPDATE 2). Does this help at all? http://stackoverflow.com/questions/7025568/java-byte-to-string-encoding-problem-on-linux – Adam Sep 09 '14 at 04:31
  • @Adam To clarify from UPDATE 2, I expect to see 1 RS character, but am instead getting tens of thousands. It would seem the Scanner is functioning perfectly, producing a new string for each one. The question now is why is the stream seeing so many, when the device sends only 1? I looked at what you linked, and it looks like they are talking about decoding issues of bytes into meaningful strings. Should not the encoding parameter to the scanner constructor have taken care of this? Should I instead be specifying the platform default encoding (is that what the stream will be in?) – Jared Sep 09 '14 at 04:40

1 Answers1

0

So it turns out I can blame this one on the device. When I sniffed the traffic to putty and executed the same sequence of commands exactly as the Java app does, I was able to reproduce the issue. It is a bug I will need to track down in the firmware. Thank you to @Adam and @MrunalGosar for your input.

Jared
  • 1,449
  • 2
  • 19
  • 40