Lecture note 5

Download Report

Transcript Lecture note 5

COMPS311F
Li Tak Sing
Case study: a multithreaded chat
server
 The source contains 3 files:
 ChatServer //the chat server
 ChatThread //the thread on the server side to handle a client
 ChatClient //the client
 The source can be obtained at:
http://plbpc001.ouhk.edu.hk/~mt311f/2010-sep/chat.zip
ChatServer
 The ChatServer class is the main program for the chat server.
 It will create a ServerSocket at port 12345. For each of the
incoming requests, a ChatThread will be created to entertain
the request.
 It is a subclass of JFrame. The window is used to display
information regarding the connected clients and messages
passed.
ChatServer
 The upper textfields will
show the connected
clients.
 The central textarea will
show the messages from
the clients.
Attributes of ChatServer
 Vector<ChatThread> threads; //connected clients
 JTextField clientText; //for displaying the connected clients
 JTextArea text; //for displaying the messages from the
clients
Methods of ChatServer
 synchronized public void addThread(ChatThread th);
//this method adds the ChatThread to threads.
 synchronized public void removeThread(ChatThread th) ;
//this method removes the ChatThread from threads.
 synchronized public void broadcast(String st);
//this method is used to send a message to all connected
clients.
ChatThread
 It is created to entertain an individual request.
 It is a subclass of Thread.
 When a ChatThread is created, it will be added to threads of
ChatServer by using the addThread method of ChatServer.
 The run method of ChatThread will continuously read from
the corresponding client. When a message is read from the
client, it will be broadcast to all connected clients through
the broadcast method of ChatServer.
 It also provide a sendMessage method for sending a message
to the corresponding client.
Attributes of ChatThread
 String name; //name of the client
 Socket socket; //socket of the connection between the
server and the client.
 ChatServer server; //the ChatServre
 DataInputStream input; //the input stream for the
connection with the client.
 DataOutputStream output; //the output stream
Constructor of ChatThread
 public ChatThread(java.net.Socket s, ChatServer server)
 This construct allows ChatThread to record the socket and the
server. The socket is used to create the data streams. The
server is used to broadcast a message.
Methods of ChatThread
 public synchronized void sendMessage(String st) throws
IOException ; //this method is used to send a message to
the client
 public void run(); //this will continuously read from the
client. After reading a message, it will invoke the server's
broadcast method to send the message to all connected
clients.
ChatClient
 It is the chat client.
 It is a subclass of JFrame.
 The top panel contains a
textfield for the user to type
in a name. This will be the id
of the client in the chat
system.
 The central textarea is used
to display all messages from
clients.
 The bottom panel contains a
textfield for the user to type
in a message.
Attributes of ChatClient
 JTextField name; //This allows the user to type in name
 JTextArea messages; //This is used to display messages from
all connected clients.
 JTextField text; //This allows the user to type in message to
be sent to all clients.
 DataInputStream input; //This is the input stream for the
connection.
 DataOutputStream output; //The output stream.
Constructor of ChatClient
 public ChatClient() ;
//the constructor does all things. It setups the window. All
listeners are created using anonymous classes. A thread is
created to continuously read from the server. When a
message is read, it will be appended to the central textarea,
messages.
Implementation of constructor of
ChatServer
...
try {
java.net.ServerSocket ss = new
java.net.ServerSocket(12345);
while (true) {
java.net.Socket s = ss.accept();
ChatThread thread = new ChatThread(s, this);
}
} catch (Exception e) {
e.printStackTrace();
}
...
Implementation of methods of
ChatServer
synchronized public void addThread(ChatThread th) {
threads.add(th);
String st = "";
for (ChatThread thread:threads) {
st+=thread.name()+" ";
}
clientText.setText(st);
}
Implementation of methods of
ChatServer
synchronized public void removeThread(ChatThread th) {
threads.remove(th);
String st="";
for (ChatThread thread:threads) {
st+=thread.name()+" ";
}
clientText.setText(st);
}
Implementation of methods of
ChatServer
synchronized public void broadcast(String st) {
text.append(st);
java.util.Vector<ChatThread> removedThreads = new
java.util.Vector<ChatThread>();
for (ChatThread th : threads) {
try {
th.sendMessage(st);
} catch (Exception e) {
removedThreads.add(th);
}
}
for (ChatThread th : removedThreads) {
removeThread(th);
}
}
Implementation of constructor of
ChatThread
public ChatThread(java.net.Socket s, ChatServer server) {
socket=s;
this.server=server;
try {
output=new java.io.DataOutputStream(socket.getOutputStream());
input=new java.io.DataInputStream(socket.getInputStream());
name=input.readUTF();
server.addThread(this);
start();
}
catch (Exception e) {
e.printStackTrace();
}
}
Implementation of methods of
ChatThread
public synchronized void sendMessage(String st) throws
IOException {
output.writeUTF(st);
}
Implementation of methods of
ChatThread
public void run() {
try {
while (true) {
String st=input.readUTF();
server.broadcast(name+":"+st);
}
}
catch (Exception e) {
server.removeThread(this);
}
}
The ActionLister of the connect
button
public void actionPerformed(ActionEvent e) {
if (button.getText().equals("connect")) {
try {
s = new java.net.Socket("127.0.0.1", 12345);
input = new
java.io.DataInputStream(s.getInputStream());
output = new
java.io.DataOutputStream(s.getOutputStream());
output.writeUTF(name.getText());
messages.append("connected\n");
button.setText("disconnect");
The ActionLister of the connect
button
new Thread() {
public void run() {
try {
while (true) {
String st = input.readUTF();
messages.append(st);
}
} catch (Exception e) {
messages.append("Disconnected\n");
button.setText("connect");
}
}
}.start();
The ActionLister of the connect
button
} catch (Exception ee) {
button.setText("connect");
messages.append("disconnected");
}
} else {
try {
input.close();
output.close();
s.close();
button.setText("connect");
messages.append("disconnected");
} catch (Exception ee) {
}
}