This lab is designed to teach you how Java's network library helps you build simple socket-based applications. First, you will build a simple client-server to figure out the basic socket usage and then you will build a chat server. I have provided a framework for you so that you can focus on the socket issues.
Copy the Server.java file to a work directory and then fill in all the places marked with a ### comment. Your goal is to create a server that prints out everything sent to it from a client. The client will connect, send lines of text, and then close the connection.
Once you have filled in the server and compiled it, use telnet as a client to test the server. In one shell type
which will start the server and have it listen for connections. Then in another shell type:
telnet localhost 8080
which will contact your server. Type in a few lines. They should appear as stdout in your server window. You can have a few classmates try to connect to your server from other machines.
Note: you can exit from telnet by typing control-] and then typing quit at the prompt:
$ telnet nexus 25 Trying 18.104.22.168... Connected to nexus.cs.usfca.edu. Escape character is '^]'. 220 nexus.cs.usfca.edu ESMTP Postfix ^] telnet> quit Connection closed. $
Your goal is to fill in the Client.java program so that it opens up a socket to localhost 8080 and sends the string "hello from java client" to the server and then disconnects. Your server should print out that line:
hello from java client
The server actually accepts more than one line so you can send multiple lines if you want to the server from your java client.
This portion requires the use of threads.
The goal here is to fill in the operations marked by ### comments so that you have a multi-threaded chat server. When a user connects, the first line of input should be their intended user name. The rest of their input is broadcast to all other connected users (i.e., not to themselves). We will use telnet as our client for this exercise.
Upon connection from a client, the server will launch a thread running a ClientHandler that will deal with reading input from that user. Each user (and their associated output stream) is registered so that upon input from anybody, the server can broadcast that to the various data output streams.
The server starts up like this:
$ java ChatServer ChatServer listening...
Then I open a telnet session in one window:
$ telnet localhost 8080 Trying ::1... Connected to localhost. Escape character is '^]'. parrt hankd: connected hankd: foo
Then "hankd" opens another client in another window:
$ telnet localhost 8080 Trying ::1... Connected to localhost. Escape character is '^]'. hankd foo
Have a few classmates connect to your server to chat.
If you get a chance, you can add a "server escape" concept where you can ask the server a question such as admin: users instead of sending a string to all users. This would be a way to find out who is lurking (i.e., listening but not saying anything).
You can have each ClientHandler examine the incoming strings to see if they start with "admin: ". If so, they can read the command following the prefix and ask the server to spit back the list of users by enumerating over the ChatServer.users Hashtable instance variable. The broadcast() method shows how this can be done. If the line does not start with the special sequence, then broadcast the string normally to everyone.