Networking and
Threads in Java

Modified

Exceptions

Exceptions allow a formal means of handling non-standard situations. For example, the following handles division by 0.

// exceptionExample.java

class exceptionExample {
   public static void main(String args[]) throws Exception {
      System.out.println("1");

      try {
         System.out.println("2");
         int x = 9/0;
         System.out.println("3");
         System.out.println(x);
      }
      catch( Exception e) {
         System.out.println("division by 0");
         System.out.println("4");
      }

      System.out.println("5");
   }
}

The output is: 1, 2, division by 0, 4, 5

Internet

Java provides simple, basic Internet protocols including TCP which supports client/server interactions, such as employed by Web servers and clients (browsers).

Internet connections have input and output streams so that communications between two computer systems can be treated much the same as reading a file or terminal console using read and print statements.

Below is a command line implementation of an echo client and server where:

  1. server opens port 1490 to listen for connections,
  2. client connects to the server on port 1490
  3. server accepts connection and blocks for input on connection,
  4. client outputs a string on connection then blocks for input,
  5. server inputs string on connection and outputs on connections, then closes the connection,
  6. clients inputs string on connection, then closes the connection.
EchoServer.java
import java.net.*;
import java.io.*;

public class EchoServer
{
   public static void main(String args[]) throws Exception
   {
         ServerSocket connection = new ServerSocket( 1490 ); // Listen on port 1490
        while(true) {
           Thread.sleep( 1000 );                                    // Thread sleeps for 1000ms.
           Socket s = connection.accept();                     // Wait for connection
	System.out.println("Connected");
			
	BufferedReader in = new BufferedReader(     // Socket input and output
                   new InputStreamReader(
                          s.getInputStream() ) );
           PrintStream out = new PrintStream(s.getOutputStream());
           String str=in.readLine();                               // Read one line to \n or \r
           out.print("Echo:"+str);                                 // Echo input to client
           System.out.println( str );                              // Echo input to console
           in.close();
           out.close();                                                  // Close file
           s.close();                                                     // Close connection
           System.out.println("Connection closed");
        }
   }
}

EchoClient.java

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

class EchoClient {
   public static void main(String args[]) throws Exception {
      String message;
       Socket s = new Socket( "localhost", 1490 );     // Echo server IP, port
      BufferedReader in = new BufferedReader(       // Buffered socket i/o
                                         new InputStreamReader(
                                               s.getInputStream() ) );
      PrintStream out = new PrintStream(s.getOutputStream());
      out.println("Hello World");                          
      message=in.readLine();                                  // read echo
      System.out.println(message );
      s.close();                                  	            // Close connection  
   }
}

To test:

  1. Open two terminal windows (command prompts),
  2. Compile and execute EchoServer.java,
  3. Compile and execute EchoClient.java

The EchoClient output should be:

Echo:Hello World

Threads

The client has several flaws:

  1. it executes only one time then exits, this can easily be solved by placing certain code inside a loop
  2. in.readLine() blocks execution, nothing else can be done until the server responds.

The second flaw is unacceptable in event-driven applications such as those with GUIs.

The solution is to place blocking calls within a separate thread.

The threaded client below has two blocking calls:

  1. System.input.readLine() to read the keyboard input, executing in the main thread,
  2. in.readLine() to read network input, executing in a child thread.
EchoThreadedClient.java
import java.net.*;
import java.io.*;

class EchoThreadedClient implements Runnable {
	static String message="Hello World";
      
	public static void main(String args[]) throws Exception {
  	         BufferedReader in = new BufferedReader(       	
                                  new InputStreamReader( System.in ) );
new Thread( new EchoThreadedClient() ).start();          // Start child thread
	         while( true ) message = in.readLine();
           }
	
	public void run() {
  	       try {
  		  while (true) {
  			  Socket s = new Socket( "localhost", 1490 );  

  			  BufferedReader in = new BufferedReader(       	// Buffered socket input and output
                              		                              new InputStreamReader( s.getInputStream() ) );
  			  PrintStream out = new PrintStream(s.getOutputStream());

  			  out.println( message );                           
			                
  			  System.out.println( in.readLine() );                   // read and print echo
  		  }
  	      }
  	      catch(Exception e){	};
	}
}

To test:

  1. Open two terminal windows (command prompts),
  2. Compile and execute EchoServer.java,
  3. Compile and execute EchoThreadedClient.java

The EchoThreadedClient output should be:

Echo:Hello World    repeated at 1000ms intervals until you type something on the keyboard

Echo: what you type on the keyboard