Search code examples
javamacossocketsbufferedreaderbufferedwriter

BufferedWriter not flushing to a socket's outstream on OS X


I'm encountering a very strange problem, that had frustrated me for the last two days. I've tried looking for similar problems here but did not find a solution.

I'm using a socket to read from a remote telnet session logger to a file, in Java.
I've defined a BufferedWriter and Reader for input and output streams, and flushed each readLine to a file. On login I get a certain string, insert a password using the outputStream, and start reading the instream in a loop. This had worked perfectly on Windows, without any problems.

Now, I've tried running the same code on Mac OS X (Yosemite). I get the first line (requesting me to insert a password), by debugging I've noticed I am also writing the password to the BufferedWriter. But, for some strange reason, on the next readLine iteration, instead of getting the log outputs, the code hangs, stuck on a the next readLine instance. If it was null it was supposed to exit the loop. I've checked opening a telnet session manually (using secureCRT) on the mac, and it works O.K, using the password. On inserting a bad password, I should also get a line ("Password incorrect). But on the next readLine I get nothing, it is just stuck.

This is my code, does anyone have any idea as to what I've done wrong here? Is it supposed to work differently on a MAC? It would really save me here. Thanks!

This fragment is a part of a thread, but it is unrelated to the problem (Or so I think). The actual file itself is created outside of the thread.

public void run(){
    String line = "-1";

    try {
        socket = new Socket(JSONReader.getPropertyByName("files/properties.json", "LOGGER_DNS_NAME"), 5550);
    } catch (IOException e1) {        
      e1.printStackTrace();
    }

    try {            
        bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        instream = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        while ((line = instream.readLine()) != null) {         

            // Insert Username and Password in the Telnet session      
            line = instream.readLine();

            if(line.startsWith("Please")){                
                bw.write("password");
                bw.newLine();
                bw.flush();               
            }           

            if (line.startsWith("Press")) {
                System.out.println("Reached log");
                bw.write("d");
                bw.newLine();
                bw.flush();
            }

            if (Thread.interrupted()){
                try {
                    instream.close();
                    bw.close();
                    socket.close();
                    return;
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("Could not close socket");
                    System.exit(-1);
                }        
            }           
        }

        // Write the output to the log file           
        logfile.println(line);
        logfile.flush();
     } catch (UnknownHostException e) {
         System.out.println("Could not open Telnet session to the server");
         System.exit(1);
     } catch  (IOException e) {
         System.out.println("There was a problem with file creation, or I/O exception");
         System.exit(1);
     }
 }

Solution

  • So finally, after sniffing the server's tcp session in both cases, I found my problem.

    the problem is that the BufferedWriter, upon using the write methods, new line and flush, automatically generates line endings (\n). Except, that on Mac OS, which is linux based, line endings are supposed to be (\r\n).

    So, instead of using the "write" method and "new line", I just inserted the \r\n string by using "append" instead (append ("password\r\n)).