Java is a great language for network programming, and for handling applications where you want to do several things at the same time.
This article shows you how we've used Java to provide a simple "chatroom" facility on our local area network - all controlled by a daemon process written in Java.
Users who want to visit the chatroom can simply telnet to port 1357 on the computer that's running the daemon, and then whatever they type in will be copied to everyone else who's logged in. The daemon will work just as well over a wide area; indeed, if you want to try it out, it's usually running on chat.wellho.net on the internet!
THE BASIC PLAN
Planning your application is vital in any object oriented language such as Java - for smaller applications you may choose to use informal methods, but for larger applications you'll need something more formal such as UML, and perhaps even tools such as Rational Rose to manage your model.
Informally, our plans for the talker are as follows:
* A single parent thread will await new connections, and
will create a new child thread when it receives a connection
* A child thread will exist for each live connection; it will
wait for input from the user of the connection, and when input
is received it will echo it to all live users.
* Threads will be managed in a Vector from which they will be
deleted when the connection is closed
* A few special directives (such as ".q" to quit) will be
provided by the application to allow users to log out, and to
enquire as to who is logged on.
Have a look through our Java code - see if you can work out how the elements fit together.
import java.net.*;
import java.io.*;
import java.util.*;
public class talker implements Runnable {
// A simple talker - Sample written by Graham Ellis, April 2001
// No login needed. Connect on port 1357.
// commands:
// .q quit
// .w who
// Variables for each thread
Socket linkto; // the socket
PrintWriter out; // the output and input streams
BufferedReader in;
int id; // i.d. of the connection
String from_name; // name of host connecting
// Class Variables
static Vector connectiontable; // current connections
static int nextid = 1; // Increasing i.d.
/////////////////////////////// Main method ////////////////////////
public static void main(String [] args) {
// Parent thread - create a server socket and await a connection
ServerSocket ss = null;
Socket s = null;
connectiontable = new Vector();
try {
ss = new ServerSocket(1357);
while ((s=ss.accept())!= null) {
// Connection received - create a thread
talker now;
Thread current = new Thread(now = new talker(s));
current.setDaemon(true);
connectiontable.addElement(now); // Save talker into vector ..
current.start(); // start the user's thread
}
}
catch (Exception e) {
System.out.println(e);
}
// should add finally block to close down
}
///////////////// Constructor for a new thread //////////////////////
talker (Socket from) {
id = nextid++;
linkto = from;
InetAddress source = linkto.getInetAddress();
from_name = source.getHostName();
try {
out = new PrintWriter(new OutputStreamWriter
(linkto.getOutputStream()));
in = new BufferedReader(new InputStreamReader
(linkto.getInputStream()));
}
catch (Exception e) {}
}
public void run () {
String line = " [User has just logged in] ";
while (true) {
boolean done=false;
// read a line from the user
if (line == null) {
try {
out.print(">: "); //prompt,flush,read
out.flush();
line = in.readLine();
} catch (Exception e) {
System.out.println(e);
done = true; // force exit if there's a problem
}
}
// Handle special cases - user input starts with "."
if (line.startsWith(".q")) done = true;
if (line.startsWith(".w")) { // build up list of host names
int k;
StringBuffer fred = new StringBuffer("WHO HERE?\n");
for (k=0;k<connectiontable.size();k++) {
talker person = (talker)connectiontable.elementAt(k);
fred.append(person.from_name);
fred.append(" ");
}
line = fred.toString();
}
// echo the line (with a header) to all users
String outline = from_name+" "+id+": "+line;
int k;
for (k=0;k<connectiontable.size();k++) {
talker person = (talker)connectiontable.elementAt(k);
person.out.println(outline);
person.out.flush(); // Vital - ensure it is sent!
}
// clear out the user if they're done
if (done) {
connectiontable.removeElement(this);
try {
out.close(); // closes needed to terminate connection
in.close(); // otherwise user's window goes mute
linkto.close();
} catch (Exception e) {}
break;
}
line = null;
}
}
}
See also
Training exercise - a talk server and client in Java
Please note that articles in this section of our
web site were current and correct to the best of our ability when published,
but by the nature of our business may go out of date quite quickly. The
quoting of a price, contract term or any other information in this area of
our website is NOT an offer to supply now on those terms - please check
back via
our main web site
Java - Putting it all together [2525] - ()
[2653] - ()
[4305] - ()
resource index - Java
Solutions centre home page
You'll find shorter technical items at
The Horse's Mouth and
delegate's questions answered at
the
Opentalk forum.
At Well House Consultants, we provide
training courses on
subjects such as Ruby, Lua, Perl, Python, Linux, C, C++,
Tcl/Tk, Tomcat, PHP and MySQL. We're asked (and answer)
many questions, and answers to those which are of general
interest are published in this area of our site.