/* * JavaTalker -- A simple duplex network talk program. * * JavaTalker allows two people on different hosts to send messages to * one another. To use JavaTalker, one user must first start JavaTalker * as a server, and then the second user can use JavaTalker to connect * to it. The communication port can optionally be specified on the * command line. * * To start JavaTalker as a server, simply run it in the Java interpreter * with the server flag: * * % java JavaTalker -server * * To then connect to the server (on the same host): * * % java JavaTalker * */ import java.applet.Applet; import java.io.*; import java.net.*; public class JavaTalker extends Applet { boolean server; // Whether we initiate or accept connections. int port = 5001; // The default port. Socket sock; // The communication socket. String host = null; // Name of the remote host. public static void main (String args[]) { new JavaTalker (args); } public JavaTalker (String args[]) { parseArgs (args); if (server) server (); else client (); } public void parseArgs (String args[]) { int i = 0; while (i < args.length) { if (args[i].equals ("-port")) { port = Integer.valueOf (args[i + 1]).intValue (); i += 2; } else if (args[i].equals ("-server")) { server = true; i++; } else if (i != args.length - 1) { System.out.println ("Usage:"); System.out.println (" (server) JavaTalker [-port port] [-server]"); System.out.println (" (client) JavaTalker [-port port] [hostname]"); System.exit (0); } else { host = args[i]; i++; } } } public void busyWait (DataInputStream inStream) { /* Currently, Java runtime thread scheduling doesn't lend itself to having simultaneous readers and writers on sockets...they tend to not notice incoming data. So we busy wait. */ try { while (inStream.available () <= 0) { Thread.currentThread ().sleep (100); } } catch (InterruptedException e) { System.out.println (e.getMessage ()); } catch (IOException e) { System.out.println (e.getMessage ()); } } public void server () { /* * As a server, we create a server socket bound to the specified * port, wait for a connection, and then spawn the reader * and writer threads. */ try { InetAddress serverAddr = InetAddress.getByName (null); System.out.println ("Waiting for connection on " + serverAddr.getHostName () + " on port " + port + "."); ServerSocket serverSock = new ServerSocket (port, 50); sock = serverSock.accept (); System.out.println ("Accepted connection from " + sock.getInetAddress() .getHostName () + "."); new JavaTalkerWriter (this).start (); new JavaTalkerReader (this).start (); } catch (IOException e) { System.out.println (e.getMessage () + "Failed to connect to client."); } } public void client () { /* * As a client, we create a socket bound to the specified port, * connect to the specified host, and then spawn the reader and * writer threads. */ try { InetAddress serverAddr = InetAddress.getByName (host); sock = new Socket (serverAddr.getHostName (), port, true); System.out.println ("Connected to server " + serverAddr.getHostName () + " on port " + sock.getPort () + "."); new JavaTalkerWriter (this).start (); new JavaTalkerReader (this).start (); } catch (IOException e) { System.out.println (e.getMessage () + ": Failed to connect to server."); } } } /* * A JavaTalkerReader takes data entered on standard input and writes * it to a socket. */ class JavaTalkerReader extends Thread { JavaTalker talker; public JavaTalkerReader (JavaTalker talker) { this.talker = talker; } public synchronized void run () { try { DataInputStream userIn = new DataInputStream (System.in); DataOutputStream remoteOut = new DataOutputStream (talker.sock.getOutputStream ()); while (true) { talker.busyWait (userIn); remoteOut.writeChars (userIn.readLine () + '\n'); } } catch (IOException e) { System.out.println (e.getMessage ()); System.out.println ("Connection to peer lost."); } } } /* * A JavaTalkerWriter takes data sent on a socket and prints it to * standard output. */ class JavaTalkerWriter extends Thread { JavaTalker talker; public JavaTalkerWriter (JavaTalker talker) { this.talker = talker; } public synchronized void run () { try { DataInputStream userIn = new DataInputStream (System.in); DataInputStream remoteIn = new DataInputStream (talker.sock.getInputStream ()); while (true) { talker.busyWait (remoteIn); System.out.println (remoteIn.readLine ()); } } catch (IOException e) { System.out.println (e.getMessage ()); System.out.println ("Connection to peer lost."); } } }