Java - Reading from a Socket using a BufferedReader object

Discussion in 'Programmer's Corner' started by integral, Dec 3, 2014.

  1. integral

    Thread Starter New Member

    Aug 19, 2010
    22
    0
    Hello,

    I need help understanding how the readline() method of a BufferedReader object works in Java.

    From what I understanding when a BufferedReader object reads from a file using the readline() method it reads the file line by line and when there is nothing left to read the method returns a null (The code labelled Example1 is an illustration of this).

    However I don’t understand how the readline() method works when reading from a socket. Please refer to the code labelled as Example 2. A Client program that connects to the server illustrated in Example 2 can send text any time and can wait long periods of time between sending text to the server.

    How does the java virtual machine know when the end of the stream related to the socket has been reached so that readline() can return null?

    Example 1:
    Code (Text):
    1.  
    2. import java.io.*;
    3.  
    4. class Reader{
    5.   public static void main(String[] args){
    6.   int lineCount = 0;
    7.    
    8.   try {
    9.     File myFile = new File("Reader.java");
    10.     FileReader fileReader = new FileReader(myFile);
    11.    
    12.     BufferedReader reader = new BufferedReader(fileReader);
    13.    
    14.     String line = null;
    15.      // *** My question is about the next line **/
    16.     while( (line = reader.readLine()) != null ) {
    17.        System.out.println(++lineCount + " " + line);
    18.     }
    19.     reader.close();
    20.     } catch (Exception ex) {
    21.       ex.printStackTrace();
    22.     }
    23.   System.out.println("lineCount = " + lineCount);
    24.   }
    25. }
    26.  

    Example 2
    Code (Text):
    1.  
    2. import java.io.*;
    3. import java.net.*;
    4. import java.util.*;
    5.  
    6.  
    7. public class VerySimpleChatServer
    8. {
    9.   ArrayList clientOutputStreams;
    10.    
    11.   public class ClientHandler implements Runnable {
    12.   BufferedReader reader;
    13.   Socket sock;
    14.    
    15.   public ClientHandler(Socket clientSOcket) {
    16.   try {
    17.   sock = clientSOcket;
    18.   InputStreamReader isReader = new InputStreamReader(sock.getInputStream());
    19.   reader = new BufferedReader(isReader);
    20.    
    21.   } catch (Exception ex) { ex.printStackTrace(); }
    22.   }
    23.    
    24.   public void run() {
    25.   String message;
    26.   try {
    27.    // *** My question is about the next line **/
    28.   while ((message = reader.readLine()) != null) {
    29.   System.out.println("read " + message);
    30.   tellEveryone(message);
    31.   }
    32.   } catch (Exception ex) { ex.printStackTrace(); }
    33.   }
    34.   }
    35.    
    36.   public static void main(String[] args) {
    37.   new VerySimpleChatServer().go();
    38.   }
    39.    
    40.   public void go() {
    41.   clientOutputStreams = new ArrayList();
    42.   try {
    43.   ServerSocket serverSock = new ServerSocket(5000);
    44.   while(true) {
    45.   Socket clientSocket = serverSock.accept();
    46.   PrintWriter writer = new PrintWriter(clientSocket.getOutputStream());
    47.   clientOutputStreams.add(writer);
    48.    
    49.   Thread t = new Thread(new ClientHandler(clientSocket));
    50.   t.start();
    51.   System.out.println("got a connection");
    52.   }
    53.   } catch (Exception ex) { ex.printStackTrace(); }
    54.   }
    55.    
    56.   public void tellEveryone(String message) {
    57.   Iterator it = clientOutputStreams.iterator();
    58.   while (it.hasNext()) {
    59.   try {
    60.   PrintWriter writer = (PrintWriter) it.next();
    61.   writer.println(message);
    62.   writer.flush();
    63.   } catch (Exception ex) { ex.printStackTrace(); }
    64.   }
    65.   }
    66. }
    67.  
    Source of Code: Head First Java 2nd edition – Chap 15
     
  2. sirch2

    Well-Known Member

    Jan 21, 2013
    1,008
    351
    In example 2 notice that the BufferedStreamReader wraps an InputStreamReader which wraps the socket InputStream. This is a way of effectively adding extra functionality to the stream, InputStreamReader only supports reading a char or a number of chars into an array. BufferedStreamReader adds readLine which presumably reads chars from the input stream and buffers them until a line ending char is encountered at which point it returns the line as a string.

    InputStreamReader.read returns -1 when the end of stream is reached, BufferedStreamReader presumbaly detects this and returns null from readLine
     
  3. integral

    Thread Starter New Member

    Aug 19, 2010
    22
    0
    Thank you for your response. I took a look at https://docs.oracle.com/javase/7/docs/api/java/io/InputStreamReader.html#read()

    However I am still curious as to what signals that the end of the stream has been reached?
    The book I am reading compares a stream to a pipe with bits going from one end to the other.
    Thinking about how a chat client works there are moments of bursts of bits when someone sends a message and long moments when no one is sending a message. However this "silence" on the pipe does not mean that the end of the stream has been reached because a message can still be sent on the pipe after a moment of "silence".

    There is "silence" on the pipe between lines 2 and 3:
    1: Person1<9:00>: hello
    2: Person2<9:00>: hello Person1
    3: Person3<9:05>: how are you?
     
  4. sirch2

    Well-Known Member

    Jan 21, 2013
    1,008
    351
    I believe it depends on the underlying protocol but for TCP at least there is no "closed" message and so it generally just relies on time outs.
     
  5. darrough

    Member

    Jan 18, 2015
    86
    19
    The server disconnects. You did not post the whole VerySimpleChatServer. Some where in the server code, "close" will be called on the ServerSocket object.
     
Loading...