This discussion is archived
7 Replies Latest reply: Apr 17, 2013 7:47 AM by gimbal2 RSS

Mac OS vs Windows problem with socket reading/writing and LabView

235461 Newbie
Currently Being Moderated
Hi,

I have inherited some code, multithreaded, with a singleton that talks to LabView over a couple ports/sockets. I'm not sure (but do not believe) the multithreading matters in this case, but mention it in case you think there might be an issue. All communications to LabView go through the singleton LabView class (instance).

When we run the code on the same MS Windows XP box as the LabView then it works properly; meaning LabView receives the commands and the java receives the results. When we run it on a Windows XP box in another room with another subnet it works fine as well. When we run it on a Mac OS in the same room/network the reader.ready() is not true within the wait time. (see the reader.ready() line in the original code).

Does anyone know why it would work for Windows but not Mac OS?

One current "guess" of what is wrong on my part is that the code below (taken out of context, otherwise the post would be really long) needs some rethinking. Any help/comments/advice on the way this is coded is greatly appreciated.

Here is the existing code.
// some declarations.
    long t0, t1;
    long waittime = 5000;
    BufferedReader reader;

    public synchronized void connectCommPort() {
        if (commportconnected != true) {
            try {
                sock = new Socket();
                InetSocketAddress endpoint = new InetSocketAddress(IPaddress, commPort);
                sock.connect(endpoint, 4000); // try to connect with a timeout of 4 seconds.
                reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
                writer = new PrintWriter(sock.getOutputStream());
                System.out.println("mec: LabV: SUCCESS - network connection to Labview command port succeeded");
                commportconnected = true;
                errorstatus = false;

            } catch (IOException ex) {
                logwriter("LabV: WARNING - network connection to Labview command port failed."+ex.toString());
                System.out.println("mec: LabV: WARNING - network connection to Labview command port failed."+ex.toString());
                commportconnected = false;
                errorstatus = true;
            }
        }
    }


    public synchronized float readpot(int potnumber) {

        String smotor = Integer.toString(potnumber);

        if (potnumber >= 0 && potnumber <= 5) {
            String message = "pot " + smotor;

            connectCommPort();

            if (commportconnected) {
                try {
                    writer.print(message + "\r\n");
                    writer.flush();
                    logwriter("LabV: [sent] " + message);
                    potvalue = potlistener();
                } catch (Exception ex) {
                    System.out.println("mec: Exception while sending command "+ex.getLocalizedMessage());
                }
                disconnectCommPort();
            }
        } else {
            if (potnumber == 7 || potnumber == 6) {
                potvalue = 5.f;
                logwriter("Faked pot reading for potnumber " + potnumber);
            } else {
                logwriter("WARNING: " + potnumber + " is not a valid pot number (must be 0 to 6)");
            }
        }
        return potvalue;
    }

    public synchronized float potlistener() {

        String message = null;
        t0 = System.currentTimeMillis();
        t1 = System.currentTimeMillis();
        boolean donereading = false;
        while ((t1 - t0) < (waittime) & donereading != true) {
            t1 = System.currentTimeMillis();
            try {

                while (reader.ready()) {
                    message = reader.readLine();
                    logwriter("LabV: [received] " + message);
                    if (message.contains(".")) {
                        potvalue = Float.parseFloat(message);
                    }
                    donereading = true;
                }  // close reader-ready-while
            } catch (Exception ex) {
                System.err.println("Exeption in potlistener() "+ex.getLocalizedMessage());
            }
        } // close timeout while loop

        return potvalue;
    }
In particular, could I readLine() in a loop where I catch the exception if it is not read and just keep trying? What is the "best way" to do this?

Here is what I was thinking, something like:
        while ( ((t1 - t0) < waittime) && !donereading ) {
            t1 = System.currentTimeMillis();
            try {
                message = reader.readLine();
                logwriter("LabV: [received] " + message);
                if (message.contains(".")) {
                    potvalue = Float.parseFloat(message);
                    donereading = true;
                }
            } catch (Exception ex) {
                System.err.println("Exeption in potlistener() "+ex.getLocalizedMessage());
            }
        } // close timeout while loop
  • 1. Re: Mac OS vs Windows problem with socket reading/writing and LabView
    235461 Newbie
    Currently Being Moderated
    Hi,

    Just to follow up. I did try the change I mentioned and now the Mac works! BUT it takes almost exactly 5 seconds to complete the readLine() method.

    I've narrowed it down by dumping System.currentTimeMillis() before and after the readLine() method.

    It still seems strange and is equal the wait time so I'm really confused :(. What am I missing!
        public synchronized float potlistener() {
    
            String message;
            t0 = System.currentTimeMillis();
            t1 = System.currentTimeMillis();
            boolean donereading = false;
            System.out.println("t0="+t0);
            while (((t1 - t0) < waittime) && !donereading) {
                t1 = System.currentTimeMillis();
                try {
                    System.out.println("time now is: "+System.currentTimeMillis());
                    message = reader.readLine();
                    System.out.println("time now is: "+System.currentTimeMillis());
                    System.out.println("elapsed time in readLine() = "+ (System.currentTimeMillis()-t1));
                    logwriter("LabV: [received] " + message);
                    System.out.println("mec: Got to potlistener loop. message = "+message);
                    if (message.contains(".")) {
                        potvalue = Float.parseFloat(message);
                        donereading = true;
                    }
                } catch (Exception ex) {
                    System.out.println("Exception in potlistener() "+ex.getLocalizedMessage());
                }
            } // close timeout while loop
            if ( !donereading ) System.out.println("mec: LabV: OOPS nothing was read within timeout limit.");
            return potvalue;
        }
  • 2. Re: Mac OS vs Windows problem with socket reading/writing and LabView
    EJP Guru
    Currently Being Moderated
    The code involving ready() is incorrect. ready() is not a valid test for EOS. Your second version is better but it doesn't check for null. This is usually written as
    while ((line = reader.readLine()) != null)
    readLine() blocks until data or EOS arrives anyway, so the ready() test is just a pointless and erroneously timing-dependent complication.
  • 3. Re: Mac OS vs Windows problem with socket reading/writing and LabView
    235461 Newbie
    Currently Being Moderated
    Thank you, EJP.

    Do you have any thoughts on the differences between the Mac OS X and the Windows XP speed? Since the previous test, the lab guys also ran the java on a linux box and it too is much faster than the Mac OS X box (does not wait 5 seconds per pot). I keep looking on the web for why there could be such a difference and find nothing.

    As regards your response, it seems to me that I could end up sitting on that line (readLine()) until forever and the surrounding loop, which seems to attempt to timeout after 5000 miliseconds is actually pointless because readLine() essentially sits there until it gets something or gets End Of Stream which could be forever if something got hung on the LabView machine. I really don't want to hang the gui if the LabView fails to respond.

    Thanks again for your response. I'll read more and try more today.
  • 4. Re: Mac OS vs Windows problem with socket reading/writing and LabView
    EJP Guru
    Currently Being Moderated
    (a) No, but I would look into the network configuration itself rather than Java code.

    (b) The correct way to enforce a read timeout is via Socket.setSoTimeout().
  • 5. Re: Mac OS vs Windows problem with socket reading/writing and LabView
    235461 Newbie
    Currently Being Moderated
    EJP: thanks again, thanks a lot for your help.
  • 6. Re: Mac OS vs Windows problem with socket reading/writing and LabView
    235461 Newbie
    Currently Being Moderated
    A year later our experiment had another cooldown and the same issue came up. This time I was able to ask someone to hook up a machine inside the rack-mount of the isolated network and test. His Mac was fine, but not the other one. It turned out to be a network configuration issue. I can not explain it because once I got it working I didn't care.

    Here is what I know. The IP I see from "outside" the facility gets routed to another IP in the facility. This is for security. Inside that LAN we have an isolated rack-mounted switch and router which houses the real server and client. This is in a test phase, in the future we will be running everything within that isolated LAN. We must figure out the routing issue (probably the next time we do a major test) because we can not rely on some DNS and external routing to bail us out.

    The solution (in this case) was to use the laboratory IP address, not the address within the rack. We use the address, not the name, so a lookup should not be required. The "server" would take 5 seconds to respond to a request when using the rack IP address. By sending the IP connection out of the rack back to the lab router (prof. IT maintained) it connected better/faster (< 1 second). Go figure. Not my current area of expertise. But I found the solution simply by matching configurations between the machines.

    Also, I did clean up all that code. I hope that it is better now. This was inherited code. I have things like this now. Sometimes I worry about the exact way I'm doing it (like waiting for 6 lines from the server) but that works right now so I'm sticking with it :)
        public synchronized float[] readpots() {
    
            String message = "pot 7";
            connectCommPort();
    
            if (commportconnected) {
                try {
                    writer.print(message + "\r\n");
                    writer.flush();
                    logwriter("LabV: [sent] " + message);
    
                    shortpotvalues = potslistener();
                } catch (Exception ex) {
                }
                disconnectCommPort();
            }
            for (int i=0; i < 7;++i)
            {
                potvalues[i] = shortpotvalues;
    }
    potvalues[7] = 5.0f;


    return potvalues;
    }

    public synchronized float[] potslistener() {
    String message = null;
    int i = 0;
    try {
    //while ((message = reader.readLine()) != null && i < shortpotvalues.length) {
    while (i < shortpotvalues.length) {
    message = reader.readLine();
    if ( message != null )
    {
    logwriter("LabV: [received] " + message);
    if (message.contains("."))
    {
    shortpotvalues[i] = Float.parseFloat(message);
    i++;
    }
    }
    else
    {
    logwriter("LabV: received NULL unexpectedly, may not have all pots correct");
    }
    } // close reader-ready-while
    } catch (ArrayIndexOutOfBoundsException aiofbex) {
    logwriter("LabV: in potslistener() Array out of bounds! " + aiofbex.toString());
    } catch (Exception ex) {
    logwriter("LabV: in potslistener() got exception: " + ex.toString());
    }
    return shortpotvalues;
    }
    Thanks for your help.
    
    Edited by: mecase on Apr 17, 2013 7:30 AM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
  • 7. Re: Mac OS vs Windows problem with socket reading/writing and LabView
    gimbal2 Guru
    Currently Being Moderated
    I find it a bit odd that there is specific exception handling for ArrayIndexOutOfBounds in there. That is a red flag for me, if your code is correct you shouldn't get one.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points