0

MyWriter.java (execute this before MyReader.java)

import java.io.*;
import java.net.*;
import java.util.* ;

public class MyWriter {

    public static void main(String[] args) throws Exception {

        ServerSocket ss = new ServerSocket(1234) ;
        System.out.println("Server started...\n\n") ;
        Socket s = ss.accept() ;

        OutputStream out = s.getOutputStream() ;

        Scanner scan = new Scanner(System.in) ;

        while(true){
            System.out.print("Enter integer (or something else to quit) : ");

            try{
                int i = scan.nextInt() ;
                out.write(i) ;
            }catch(RuntimeException rte){
                System.out.println("\n\n") ;
                rte.printStackTrace() ;
                System.out.println("\n\n") ;
                break ;
            }
        }
    }
}

MyReader.java (only executed, when done with MyWriter.java)

import java.io.*;
import java.net.*;
import java.util.* ;

public class MyReader {

    public static void main(String[] args) throws Exception {

        Socket s = new Socket("localhost", 1234) ;

        InputStream is = s.getInputStream() ;

        int i ;
        while( (i = is.read()) != -1 ){
            System.out.println( "character form : " + (char)i + ", int form : " + i);
        }
    }
}

Problem : MyReader is not getting terminated, even if I am passing -1 in MyWriter.

2
  • Does MyWriter terminate? It should print a stack trace and the process should exit. If it doesn't, then the socket is still open, and the reader will block waiting for more input. Commented Oct 19, 2009 at 19:52
  • it only terminates for a non-integer value (Exceptions are not properly handled to keep code pointing to exact problem). otherwise, it is in while(true) loop. Consider, that my input is only integer with one of the possible input -1, for which MyReader gets terminated, but it don't getting terminated. Commented Oct 19, 2009 at 19:57

2 Answers 2

3

Read returns an int so that it can also indicate the end of the stream, as -1. If the signature were

byte read()

then you'd never know when the stream had ended (unless it threw an exception, I suppose).

I suspect there's no particular reason for write to take an int - it seems a slightly strange choice to me. The Javadoc specifically says that the higher 24 bits are ignored. Maybe this is just an accident of history.

(In .NET, Stream.ReadByte returns an int, but Stream.WriteByte takes a byte. This makes more sense IMO.)

Now, with that background, when you write "-1" to your stream, you're actually writing the value "255" - and that's what you read back. "-1" is represented in binary as "all 1s" so the lower 8 bits of that are "11111111" which is 255 when considered as an unsigned value.

Your reader will only terminate when you close the output stream in the "writing" application - because that's when read() will return -1.

Sign up to request clarification or add additional context in comments.

3 Comments

then why here MyReader is not getting terminated for -1 input.
I got this from Java RMI by William Grosso :- The fact that the argument to the basic write( ) method is an integer is somewhat peculiar. Recall that read( ) returned an integer, rather than a byte, in order to allow instances of InputStream to signal exceptional conditions. write( ) takes an integer, rather than a byte, so that the read and write method declarations are parallel. In other words, if you've read a value in from a stream, and it's not -1, you should be able to write it out to another stream without casting it.
Hmm. I'd argue that that's an edge case and not worth bending the API out of shape for. It means that every implementation of OutputStream has to do the cast instead, effectively... and the signature doesn't reflect the meaning. Bad decision IMO.
0

The best way of figuring out what is wrong with the code is to debug it, besides looking at the java doc.

In this case the read method will not return -1 unless it reaches the end of the stream, the values that are returned by the method are between 0 and 255 otherwise.

This is the Java Doc of the method:

/**
 * Reads the next byte of data from the input stream. The value byte is
 * returned as an <code>int</code> in the range <code>0</code> to
 * <code>255</code>. If no byte is available because the end of the stream
 * has been reached, the value <code>-1</code> is returned. This method
 * blocks until input data is available, the end of the stream is detected,
 * or an exception is thrown.
 *
 * <p> A subclass must provide an implementation of this method.
 *
 * @return     the next byte of data, or <code>-1</code> if the end of the
 *             stream is reached.
 * @exception  IOException  if an I/O error occurs.
 */

I have rewritten the class in order to facilitate debugging:

import java.io.InputStream; import java.net.Socket;

public class MyReader {

public static void main(String[] args) throws Exception {
    Socket s = new Socket("localhost", 1234);
    InputStream is = s.getInputStream();

    int i;
    do {
        i = is.read();
        System.out.println("character form : " + (char) i + ", int form : " + i);
    } while (i != -1);
}

}

have fun ;)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.