Title: Networking
Course: CPS 261: Advanced Java Concepts ~ DL & MM MASTER

Networking

Reading:

Java Tutorial : Custom Networking

Socket Programming

ServerSockets:

TCP/IP is that standard Protocol that almost everything uses. A Socket is a Class that allows you to communicate with others using TCP/IP. Email, HTTP, FTP, etc. all use Sockets and TCP/IP. The concept of Sockets originated With Berkeley Unix with the C Programming language. The notion of Sockets has been implemented on many platforms including Java.

Java provides 2 Socket classes. One for the Server and one for anyone wanting to connect to a server. Any useable Server Socket is associated with a Port number.

In order for a client to connect to a Server Socket, the client needs to know the Server's port number as well as the Server's address. The Server's name can be represented by the InetAddress class. If you want to find the InetAddress of the machine that you are currently executing on, call
InetAddress.getLocalHost().
This class allows you to see the IP-Address this associated Socket through the
getHostAddress method, and the DNS-associated name through the
getHostName method.

The key method on the ServerSocket is the accept method. This method is called when a Client attempts to connect to your Server. The accept method returns a Socket class associated with the Connecting Client. To communicate with the Client, the Socket class provides getOutputStream and getInputStream methods to return an OutputStream and InputStream. Through these stream based classes we can send to the Client and receive from the client.

EchoServer.java


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

public class EchoServer {

 public static void main(String[] args) throws IOException {
     int portNum = 4444;
     InetAddress iaddr=null;
     if (args.length > 0)
     {
         portNum = Integer.parseInt(args[0]);
     }

     ServerSocket serverSocket = null;

     try {
            serverSocket = new ServerSocket(portNum);
            iaddr = InetAddress.getLocalHost();
            System.out.println("Host:" + iaddr.getHostName()+
                 " ipaddr=" + iaddr.getHostAddress()+
                 " portnum="+ portNum);
        }
     catch (IOException e)
        {
            System.err.println("Socket Err:" + e);
            System.exit(1);
        }

     Socket clientSocket = null;

     try{
            clientSocket = serverSocket.accept();
        }
     catch (IOException e) {
            System.err.println("Accept failed." + e);
            System.exit(1);
        }

     PrintWriter out = new PrintWriter(
                           clientSocket.getOutputStream(), true);

     BufferedReader in = new BufferedReader(
               new InputStreamReader(
                       clientSocket.getInputStream()));

     String inputLine, outputLine;

     while ((inputLine = in.readLine()) != null) // Read from socket
       {
             out.println(inputLine); // Echo data read
        }
     out.close();
     in.close();
     clientSocket.close();
     serverSocket.close();
    }
}


Client Sockets:

When we are the Client, we want to use the Socket class instead of the ServerSocket class. The constructor to the Socket class takes an address and a port number. The address can be something like "gettysburg.wccnet.org", or "198.111.176.24".

Once the socket it created, you can call the getLocalAddress method of the Socket to obtain an InetAddress associated with the Server. Just like before, the InetAddress provides getHostName and getHostAddress methods.

Also just like before, we can call getOutputStream and getInputStream methods to obtain OutputStream and InputStream classes to communicate with out server.

EchoClient.java


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

public class EchoClient {
  public static void main(String[] args) throws IOException {

        Socket echoSocket = null;
        PrintWriter out = null;
        BufferedReader in = null;
        InetAddress iaddr;

        if (args.length < 2)
        {
            System.out.println("Usage java EchoClient Host portNum");
            return;
        }

        try
        {
            echoSocket = new Socket(args[0], Integer.parseInt(args[1]));
            iaddr = echoSocket.getLocalAddress();
            System.out.println("getHostName = " + iaddr.getHostName());
            System.out.println("getHostAddress = " + iaddr.getHostAddress());

            // Create in/out classes associated with the Open Socket

            out = new PrintWriter(echoSocket.getOutputStream(), true);

            in = new BufferedReader(
                   new InputStreamReader(
                       echoSocket.getInputStream()));

        }
        catch (UnknownHostException e)
        {
            System.err.println("Cant find host: "+ e);
            System.exit(1);
        }
        catch (IOException e)
        {
            System.err.println("Couldn't get I/O: " +e);
            System.exit(1);
        }

        // Create Input class for the Keyboard

        BufferedReader keyboard = new BufferedReader(
           new InputStreamReader(System.in));

        String userInput;

        while ((userInput = keyboard.readLine()) != null) // Read from Socket
        {
            out.println(userInput); // Write to socket
            System.out.println(in.readLine());
        }

        out.close(); // Close output stream side of the socket
        in.close();  // Close input stream side of socket
        keyboard.close(); // Close keyboard
        echoSocket.close();  // Close the socket
  }// end of main
}// end of EchoClient class



EchoMulti.java

The main thing new in this example is the structure. We have a Mother Server task that merely waits for the initial client connect by calling accept. Once an accept call returns, the mother farms out the actual management of the conversation on that connection to another thread. This allows the Mother task to handle multiple conversations at a time and still manage to wait for new connections.


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

public class EchoMulti {
    public static void main(String[] args) throws IOException {

     int portNum = 4444;
     InetAddress iaddr=null;
     ServerSocket serverSocket = null;

     if (args.length > 0)
     {
         portNum = Integer.parseInt(args[0]);
     }

     try {
            serverSocket = new ServerSocket(portNum);
            iaddr = InetAddress.getLocalHost();
            System.out.println("Host:" + iaddr.getHostName()+
                 " ipaddr=" + iaddr.getHostAddress()+
                 " portnum="+ portNum);
        }
     catch (IOException e)
        {
            System.err.println("Socket Err:" + e);
            System.exit(1);
        }

     boolean listening = true;
     Socket nextSock;
     int nThreadCount=0;

     while (listening)
     {
         nextSock = serverSocket.accept();
         Thread echoChild;
         System.out.println(nThreadCount +" Another Thread Created");

       // Create a thread to process incoming connection
         echoChild = new EchoMultiChild(nextSock, nThreadCount++);
         echoChild.start();
      }

      serverSocket.close();
    }
}



EchoMultiChild.java


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

public class EchoMultiChild extends Thread {
    private Socket socket = null;
    int myIndex;
    PrintWriter out=null;
    BufferedReader in = null;

    public EchoMultiChild(Socket s, int me)
    {
       socket = s;
       myIndex= me;
    }

    public void run()
    {

       try {
            out = new PrintWriter(socket.getOutputStream(), true);

            in = new BufferedReader( new InputStreamReader(
                           socket.getInputStream()));

            String inputLine, outputLine;

            while ((inputLine = in.readLine()) != null) // Read from socket
            {
               out.println(inputLine); // Echo data read
            }
           }
       catch (IOException e)
           {
             System.out.println("EchoMultiChild Err: " + e);
             e.printStackTrace();
           }
       finally
           {
             try
             { // I'm annoyed that I need try ... catch to keep the compiler happy here
                out.close();
                in.close();
                socket.close();
                System.out.println(myIndex + ": Thread Exitting");
             } catch (Exception e){}
           }
    }// end of run routine
}


Reading and Writing Serialized Objects across Sockets

Suppose that you need to pass more sophisticated objects than strings across the network. After all you are creating a game that has lots of different data types. You could figure out a way to convert your complicated game structure into a series of strings and then convert the strings back to your game structure. But this is a lot of work. Especially if someone tells you that Java can automically figure out how to pass a class across the network.

So lets rewrite the above Echo Server/Client to pass a class across the network instead of a string. I have highlighted the key Java tricks to make this class transferable across the network. Suppose that the class we want to pass across looks like the following:


import java.io.Serializable;
import java.util.Date;
import java.util.ArrayList;

// A serializable class that can be easily read and written
// to a socket.  Note that all of your classes must implement
// Serializable.  If you include some one elses class, make
// sure they too implement Serializable.  Note that most
// Java classes (like String, Date, ArrayList, etc.) do
// implement Serializable

public class UserInputs implements Serializable
{
    int counter=0;
    String lastMessage; // already serializable
    ArrayList list = new ArrayList(); // already serializable

// endOfLine will be '\r\n' on Windows and '\n' on Linux
    String endOfLine = System.getProperty("line.separator");

// BEGIN INNER CLASS
    class Data implements Serializable

    {
        Date date; // already serializable
        String str;
        Data(String s)
        {
            date = new Date();
            str =s;
        }

// toString makes it easy to create output of this class
        public String toString()
        {
            return date +" " + str;
        }
    }
 // END INNER CLASS

    void addMsg(String s)
    {
        list.add( new Data(s));
        counter += 1;
        lastMessage = s;
    }

// toString makes it easy to create output of this class
    public String toString()
    {
        String retval;
        retval = "counter="+counter +" lastMessage="+ lastMessage + endOfLine;
        for (int i=0; i < list.size(); i++)
            retval += list.get(i) + endOfLine;
        return retval;

    }
}


New Client Echo Program


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

public class EchoClient {
  public static void main(String[] args) throws IOException {

        Socket echoSocket = null;
        ObjectOutputStream out=null;
        ObjectInputStream in = null;
        InetAddress iaddr;

        if (args.length < 2)
        {
            System.out.println("Usage java EchoClient Host portNum");
            return;
        }

        try
        {
            echoSocket = new Socket(args[0], Integer.parseInt(args[1]));
            iaddr = echoSocket.getLocalAddress();
            System.out.println("getHostName = " + iaddr.getHostName());
            System.out.println("getHostAddress = " + iaddr.getHostAddress());

            // Create in/out classes associated with the Open Socket

            out = new ObjectOutputStream(echoSocket.getOutputStream());
            in = new ObjectInputStream(echoSocket.getInputStream());


        }
        catch (UnknownHostException e)
        {
            System.err.println("Cant find host: "+ e);
            System.exit(1);
        }
        catch (IOException e)
        {
            System.err.println("Couldn't get I/O: " +e);
            System.exit(1);
        }

        // Create Input class for the Keyboard

        BufferedReader keyboard = new BufferedReader(
           new InputStreamReader(System.in));

        UserInputs userInputs = new UserInputs();
        String str;

        try
        {
            while ((str = keyboard.readLine()) != null) // Read from Keyboard
            {
                userInputs.addMsg(str);
                out.writeObject(userInputs);
                out.reset(); // This is needed
                               // when  reusing the same object

                UserInputs ui = (UserInputs)in.readObject();

                System.out.println("Echo from socket: "+ui);
            }
        }
        catch (ClassNotFoundException e)
        {
            System.out.println(" ClassNotFoundException: " + e);
        }

        out.close(); // Close output stream side of the socket
        in.close();  // Close input stream side of socket
        keyboard.close(); // Close keyboard
        echoSocket.close();  // Close the socket
  }// end of main
}// end of EchoClient class





Note that EchoMulti.java is unchanged.

EchoMultiChild.java


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

public class EchoMultiChild extends Thread {
    private Socket socket = null;
    int myIndex;
    ObjectOutputStream out=null;
    ObjectInputStream in = null;



    public EchoMultiChild(Socket s, int me)
    {
       socket = s;
       myIndex= me;
    }

    public void run()
    {

       try {
            out = new ObjectOutputStream(socket.getOutputStream());
            in = new ObjectInputStream(socket.getInputStream());

            UserInputs ui;
            while ((ui = (UserInputs)in.readObject()) != null) // Read from socket
            {
               out.writeObject(ui); // Echo data read
               System.out.println("Just read: " + ui);
            }
           }
       catch (ClassNotFoundException e)
       {
            System.out.println("ClassNotFoundException: "+e);
       }
       catch (IOException e)
           {
             System.out.println("EchoMultiChild Err: " + e);
             e.printStackTrace();
           }
       finally
           {
             try
             { // I'm annoyed that I need try ... catch to keep the compiler happy here
                out.close();
                in.close();
                socket.close();
                System.out.println(myIndex + ": Thread Exitting");
             } catch (Exception e){}
           }
    }// end of run routine
}





Take a look at theATM/Banklog exercise. See if you can rework it so that the ATM threads use networking so that the ATM threads read their input from a Socket instead of a file.

GetUrl.java

In this example, we are still using Socket programming, but we are using enough knowledge of HTTP to look like a primitive browser.


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

// Issue commands like:
//   java GetUrl russet.wccnet.org /~chasselb/boys_names.txt
//   java GetUrl russet.wccnet.org /~chasselb/girls_names.txt
//   java GetUrl wccnet.edu
//   java GetUrl yahoo.com



public class GetUrl {
  public static void main(String[] args) throws IOException {

        Socket urlSocket = null;
        PrintWriter out = null;
        BufferedReader in = null;
        InetAddress iaddr;
        String Url;
        String Host;

        if (args.length < 2)
        {
            System.out.println("Usage java GetUrl Host Url");
            return;
        }
        Host = args[0];
        Url = args[1];

        try
        {
            urlSocket = new Socket(Host, 80); // Web servers run on port 80
            iaddr = urlSocket.getLocalAddress();
            System.out.println("getHostName = " + iaddr.getHostName());
            System.out.println("getHostAddress = " + iaddr.getHostAddress());

            // Create in/out classes associated with the Open Socket

            out = new PrintWriter(urlSocket.getOutputStream(), true);

            in = new BufferedReader(
                   new InputStreamReader(
                       urlSocket.getInputStream()));

        }
        catch (UnknownHostException e)
        {
            System.err.println("Cant find host: "+ e);
            System.exit(1);
        }
        catch (IOException e)
        {
            System.err.println("Couldn't get I/O: " +e);
            System.exit(1);
        }

        String response;
        // Enough HTTP to fake out that we are a browser

        out.println("GET "+Url + " HTTP/1.1" + "\r\n" +
                    "Host: " + Host + "\r\n" + "\r\n");


        while ((response = in.readLine()) != null) // Read from Socket
        {
            System.out.println(response);
        }

        out.close(); // Close output stream side of the socket
        in.close();  // Close input stream side of socket
        urlSocket.close();  // Close the socket
  }// end of main
}// end of getUrl class



URLReader.java

Java provides a URL class that allows you to use HTTP at a little higher level than Socket programming. Note that the URL constructor includs the URL string. By calling openStream, you can obtain an InputStream class instance. From this class, you can read back your results (probably the contents of an Html file). Note that you don't need to know any HTTP command sequences. Also you don't have to strip off any HTTP Server protocol wrappers like you might have in GetUrl.java above.


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

// Try:
//   java URLReader russet.wccnet.org/~chasselb/boys_names.txt
//   java URLReader russet.wccnet.org/~chasselb/girls_names.txt
//   java URLReader wccnet.edu
//   java URLReader yahoo.com


public class URLReader {
    public static void main(String[] args) throws Exception
    {
    String urlString;
    URL myUrl;
    String parms="";
    InputStreamReader myReader;
    InputStream inStream;

    if (args.length < 1)
    {
        System.out.println("Useage: java URLReader URL ");
        return;
    }
    urlString = args[0];
  // ********************************************
    myUrl = new URL("http://"+urlString);

    inStream = myUrl.openStream();
    myReader = new InputStreamReader(inStream);
    BufferedReader in = new BufferedReader(myReader);

    String inputLine;

    while ((inputLine = in.readLine()) != null)
        System.out.println(inputLine);

    in.close();
    }
}



Another Thing to try:

After the Line of stars, add the following code:


 if (args.length > 1)
    {
      for (int i=1; i < args.length; i++)
      {
        parms += args[i] + " ";
      }
      parms = URLEncoder.encode(parms);
      urlString += "?name="+parms;
    }



Issue the command:
java URLReader gettysburg.wccnet.org:7780/hmk_data_web/java269/greatPerson.jsp George M Apple

This demonstrates Encoding Parameters into a URL. Note that URLEncoder.encode will do all of the dirty work for you.

ParseURL.java


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

public class ParseURL {
    public static void main(String[] args) throws Exception {
        URL aURL = new URL("http://java.sun.com:80/docs/books/tutorial/intro.html#DOWNLOADING");
        System.out.println("protocol = " + aURL.getProtocol());
        System.out.println("host = " + aURL.getHost());
        System.out.println("filename = " + aURL.getFile());
        System.out.println("port = " + aURL.getPort());
        System.out.println("ref = " + aURL.getRef());
    }
}


Snoop:


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

public class SnoopMom {
    public static void main(String[] args) throws IOException {

     int portNum = 4444;
     InetAddress iaddr=null;
     ServerSocket serverSocket = null;
     String host="gettysburg.wccnet.edu";
     int hostPort = 80;

     if (args.length > 0)
     {
         portNum = Integer.parseInt(args[0]);
     }

     try {
            serverSocket = new ServerSocket(portNum);
            iaddr = InetAddress.getLocalHost();
            System.out.println("Host:" + iaddr.getHostName()+
                 " ipaddr=" + iaddr.getHostAddress()+
                 " portnum="+ portNum);
        }
     catch (IOException e)
        {
            System.err.println("Socket Err:" + e);
            System.exit(1);
        }

     boolean listening = true;
     Socket nextSock;
     int nThreadCount=0;

     while (listening)
     {
         nextSock = serverSocket.accept();
         Thread client2server, server2client;
         System.out.println(nThreadCount +" Another Thread Created");

       // Create a thread to process incoming connection
         client2server = new Client2ServerChild(nextSock, host, hostPort, nThreadCount++);
         client2server.start();

      }

      serverSocket.close();
    }
}


//**********************************************


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

public class Client2ServerChild extends Thread {
    private Socket inSocket = null;
    private Socket outSocket = null;
    int myIndex;
    //BufferedOutputStream out=null;
    //BufferedInputStream in = null;
    BufferedReader in = null;
    PrintStream out = null;
    Server2ClientChild server2client=null;

    public Client2ServerChild(Socket s, String host, int hostPort, int me)
    throws IOException
    {
    	inSocket = s;
    	outSocket = new Socket(host, hostPort);
    	System.out.println("Socket created for "+host + " " + hostPort);
        myIndex= me;
        server2client = new Server2ClientChild(inSocket, outSocket, me);
        server2client.start();
    }

    public void run()
    {
       int max_size=1024;
       byte[] buffer = new byte[max_size];
       int numRead;
       String str;

       System.out.println("Client2Server running");

       try {
            out = new PrintStream(outSocket.getOutputStream());

            in = new BufferedReader( new InputStreamReader(
            		inSocket.getInputStream()));
            System.out.println("******** Client2Server *****");
            int count = 1;
            do
            {
            	str = in.readLine();
            	if (count++ == 2)            	
            		str = "Host: gettysburg.wccnet.edu:80";
            	
            	out.println(str);	
            	System.out.println(str);
            	
            } while (str != null);
            System.out.println("**********************");
           }
       catch (IOException e)
           {
             System.out.println("Client2ServerChild Err: " + e);
             e.printStackTrace();
           }
       finally
           {
             try
             { // I'm annoyed that I need try ... catch to keep the compiler happy here
                out.close();
                in.close();
                System.out.println(myIndex + ": Thread Exitting");
             } catch (Exception e){}
           }
       System.out.println("Client2Server exitting");
    }// end of run routine
}

// ***********************************************

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

public class Server2ClientChild extends Thread {
	private Socket inSocket = null;
    private Socket outSocket = null;
    int myIndex;
    BufferedOutputStream out=null;
    BufferedInputStream in = null;

    public Server2ClientChild(Socket inSocket, Socket outSocket, int me)
    {
       this.inSocket = inSocket;
       this.outSocket = outSocket;
       myIndex= me;
    }

    public void run()
    {
       int max_size=1024;
       byte[] buffer = new byte[max_size];
       int numRead;
       System.out.println("Server2Child running");

       try {
            out = new BufferedOutputStream(inSocket.getOutputStream());

            in = new BufferedInputStream(
            		outSocket.getInputStream());

            do
            {
            	numRead = in.read(buffer, 0, max_size);
            	if (numRead > 0)
            	{
            		out.write(buffer, 0, max_size);
            		System.out.println("******** Server2Client *****");
            		System.out.write(buffer,0, max_size);
            		System.out.println("**********************");
            	}
            } while (numRead > 0);
           }
       catch (IOException e)
           {
             System.out.println("Server2ClientChild Err: " + e);
             e.printStackTrace();
           }
       finally
           {
             try
             { // I'm annoyed that I need try ... catch to keep the compiler happy here
                out.close();
                in.close();
                System.out.println(myIndex + ": Thread Exitting");
             } catch (Exception e){}
           }

       System.out.println("Server2Child exitting");
    }// end of run routine
}





ShowDocument.java


/*
 * 1.1 version.
 */

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import java.net.MalformedURLException;

public class ShowDocument extends Applet
                          implements ActionListener {
    TextField urlField;
    Choice choice;
    AppletContext context;

    public void init() {

    context = getAppletContext();
    setLayout(new GridLayout(0,1));

    Label label1 = new Label("URL of document to show:",
                                 Label.LEFT);
    add(label1);

    urlField = new TextField("http://wccnet.edu/", 50);
    urlField.addActionListener(this);
    add(urlField);

    Label label2 = new Label("Window/frame to show it in:",
                                 Label.LEFT);
    add(label2);

    choice = new Choice();
    choice.addItem("(browser's choice)"); //don't specify
    choice.addItem("My Personal Window"); //a window named
                                        //"My Personal Window"
    choice.addItem("_blank"); //a new, unnamed window
    choice.addItem("_self");
    choice.addItem("_parent");
    choice.addItem("_top"); //the Frame that contained this applet
    add(choice);

    Button button = new Button("Show document");
    button.addActionListener(this);
    add(button);

    }

    public void actionPerformed(ActionEvent event) {
        String urlString = urlField.getText();
        URL url = null;
        try {
            url = new URL(urlString);
            context.showStatus("Mine: "+urlString);
            if (url != null) {
                if (choice.getSelectedIndex() == 0)
                    context.showDocument(url);
                else
                    context.showDocument(url,
                                  choice.getSelectedItem());
                }
            }
        catch (MalformedURLException e)
            {
                System.err.println("Malformed URL: " + urlString);
            }
    }
}


Other Examples - I have some other examples that I don't plan to present. Some of these are too complex and others don't seem to be as important. I have a Chat Server Program and some datagram programs in this section.

Exercises

1. Create a Server that delivers One Liners. You can have your server cycle through your One-liners, or you can use a random number approach to delivering one-liners. Provide the following commands for your One-Liner Service:
  - Count - This command will return the Number of One-Liners
  - Fetch N - This command will return the N'th One-Liner
  - Fetch - This command will return a Random One-Liner
  - Bye
Your Server should be a Multi-Threaded Server. A sample list of one-liners follows:


Life is wonderful. Without it we'd all be dead.
Daddy, why doesn't this magnet pick up this floppy disk?
Give me ambiguity or give me something else.
I.R.S.: We've got what it takes to take what you've got!
We are born naked, wet and hungry. Then things get worse.
Make it idiot proof and someone will make a better idiot.
He who laughs last thinks slowest!
Always remember you're unique, just like everyone else.
"More hay, Trigger?" "No thanks, Roy, I'm stuffed!"
A flashlight is a case for holding dead batteries.
Lottery: A tax on people who are bad at math.
Error, no keyboard - press F1 to continue.
There's too much blood in my caffeine system.
Artificial Intelligence usually beats real stupidity.
Hard work has a future payoff. Laziness pays off now.
"Very funny, Scotty. Now beam down my clothes."
Puritanism: The haunting fear that someone, somewhere may be happy.
Consciousness: that annoying time between naps.
Don't take life too seriously, you won't get out alive.
I don't suffer from insanity. I enjoy every minute of it.
Better to understand a little than to misunderstand a lot.
The gene pool could use a little chlorine.
When there's a will, I want to be in it.
Okay, who put a "stop payment" on my reality check?
We have enough youth, how about a fountain of SMART?
Programming is an art form that fights back.
"Daddy, what does FORMATTING DRIVE C mean?"
All wiyht. Rho sritched mg kegtops awound?
My mail reader can beat up your mail reader.
Never forget: 2 + 2 = 5 for extremely large values of 2.
Nobody has ever, ever, EVER learned all of WordPerfect.
To define recursion, we must first define recursion.
Good programming is 99% sweat and 1% coffee.
Home is where you hang your @
The E-mail of the species is more deadly than the mail.
A journey of a thousand sites begins with a single click.
You can't teach a new mouse old clicks.
Great groups from little icons grow.
Speak softly and carry a cellular phone.
C:\ is the root of all directories.
Don't put all your hypes in one home page.
Pentium wise; pen and paper foolish.
The modem is the message.
Too many clicks spoil the browse.
The geek shall inherit the earth.
A chat has nine lives.
Don't byte off more than you can view.
Fax is stranger than fiction.
What boots up must come down.
Windows will never cease.   (ed. oh sure...)
In Gates we trust.    (ed.  yeah right....)
Virtual reality is its own reward.
Modulation in all things.
A user and his leisure time are soon parted.
There's no place like http://www.home.com
Know what to expect before you connect.
Oh, what a tangled website we weave when first we practice.
Speed thrills.
Give a man a fish and you feed him for a day; teach him to use the Net and he won't bother you for weeks.



2. Write a Cmd Server --- Executes FileManger (see the I/O section) on another server. .
3. Add 2 new commands to the Cmd Server : Fetch, Put ----
First line of input contains command along with the relavent filename(Restrict to text)
4. Create an ATM Server. Each ATM client simulates an ATM machine. The ATM server logs the requests in a master log file.
5. Write a Simple Chat program. The client program prompts for a user name and then spawns 2 tasks. The one task waits for keyboard input and then sends the user name + new message to the Chat Server. The other task waits for data received from the Chat Server.
Cleaned up solution from In Class Exercise
6. Write a Snoop program. Snoop is a program that slips in between a client and a server and prints out the contents of the conversation.
7. Write a Rock, Paper, Scissors Server.

Last Modified: October 10, 2012 10:44 AM