Questions / Clarifications on TCP/IP Sockets on CRIO

Hi -

I’m new to network socket code under the J2ME on the CRIO this year. So I have a couple of questions or clarifications to make sure that I understand why our code is doing what it does. I’ve tried reasoning it from the couple of threads that seem to be related - but no one is asking (or answering) the underlying generic question :wink:

Thanks in advance!
Stu

I’m basing my assumptions on what I know of Java :wink: and the javadoc of the API provided with the Eclipse plugins:

plugins/edu.wpi.first.javadev.sunspotfrcsdk_1.0.7.1/sunspotfrcsdk/doc/javadoc/index.html

which says it’s the “2012 Java FRC API”.

(1) It would appear that the BufferedReader class, although it can be constructed without any problems, does nothing useful / according to the javadoc of the API - the call to read never returns. There was one thing I found on Google that seemed to confirm that - but I wanted to make sure. Specifically this hangs forever:

BufferedReader br = new BufferedReader( new InputStreamReader(
                sock.openDataInputStream( ) ) );

 numRead = br.read( message ) ) != -1

We started with this on a laptop with the full Java 2 SDK, and it worked fine with the server.

(2) It would appear that the InputStreamReader class has the same problem. If you specify a number of characters to read in the call, if you happen to have that many hanging around it will return, but as soon as you hit the end of the sent stream, it hangs until you get enough to match it. Specifically

 InputStreamReader isr = new InputStreamReader(
                sock.openInputStream( ) );

 numRead = isr.read( message, 0, 5 ) ) != -1

works to keep reading the characters in the stream until you get to the end and have less than 5 characters, at which point it hangs until the next response comes back.

(3) So, the only way to read characters off a socket is one at a time, using either InputStream or InputStreamReader:

 numRead = isr.read( message, 0, 1 ) ) != -1

This seems consistent with all the programming examples I could find for J2ME socket programming (which I just assumed was because they were doing the simplest examples, rather than showing the only way to do it).

This also seems somewhat consistent with what is in some of the WPIlib code (e.g., the Reader class). But again, I just wanted to make sure - as it seems kind of funny to provide classes in the API implementation that don’t work (according to the way I read the javadoc) … and certainly don’t work the same way as they do on a full Java 2 level.

(4) Of course that means that you need to deal with the fact that it will always block if you try to read past the end of characters waiting - so your reader (in an implementation that is sending something off the robot to a server and getting a response back) has to make sure to never try and read past the end of the response.

(5) The other weird thing is that the equivalent output classes seem to work fine:

        BufferedWriter bw = new BufferedWriter( new OutputStreamWriter(
                sock.openOutputStream( ) ) );
        bw.write( outLine );

which apparently helped to throw me further off.

We use the readLine() of a BufferedReader to fetch an entire string ending with a
character. I believe you are correct on the reading the input character at a time otherwise.

See [1] for our java code that accepts a tcp connection and reads out strings. You want to look in acceptConnections() and update(). Some of our code is still a little messy in here, but it works and we have the code reading a string a 9 numbers terminated by a newline character.

If you need some scripts to help you debug your work, try [2] and [3]. Hopefully this will get you on your way to debugging the networking. If you need another example to look at, the WPILIB has networktables code which is how we learned more about creating the sockets without further examples in the documentation.

[1] https://github.com/jesusrambo/WPILIBJ/blob/master/WPILibJ/src/edu/team2035/meta/MetaTCPVariables.java

[2] http://dl.dropbox.com/u/16839218/robotics/tcpserver.py

[3] http://dl.dropbox.com/u/16839218/robotics/tcpclient.py

why python?