IM269 Coursework 2: EchoServer.java
// IM269 - Coursework 2: Echo Client/Server
// Semester A, 2nd November 1998
// Eamonn Martin (BSc Computing)
// Student ID: 96/D59682
// efm001@unl.ac.uk
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
// EchoServer window
class ServerWindow extends AppWindow {
private TextArea log;
// Constructor
ServerWindow(String title) {
super(title);
Button b;
Panel p;
p = new Panel(new BorderLayout()); // Server log
p.add(new Label("Transaction Log:"), "North");
p.add(log = new MessageArea());
add(p);
p = new Panel(new GridLayout()); // Button panel
b = new Button("Reset"); // Reset button
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { resetServer(); }
});
p.add(b);
b = new Button("Quit"); // Quit button
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { dispose(); }
});
p.add(b);
add(p, "South");
setBackground(SystemColor.control); // Set background colour
setSize(350, 250); // Set window size
setVisible(true); // Display the window
resetServer(); // Initialize the server
}
// Reset the server
private void resetServer() {
log.setText(""); // Empty transaction log
EchoServer.num = 0; // Reset transaction number
println("EchoServer Transaction Log");
println(new java.util.Date().toString());
println("EchoServer listening on port " + EchoServer.port + "...");
}
// Write a string to the transaction log area
void println(String s) { log.append(s + "\n"); }
// Close the server socket
public void windowClosed(WindowEvent e) {
try { // Close the server socket (if open)
if (EchoServer.socket!=null) EchoServer.socket.close();
} catch (IOException x) { // Whatever...
} finally { super.windowClosed(e); } // Terminate Java system
}
}
// Client transactions
class Transaction extends Thread {
private Socket socket; // Client socket
private String id; // Transaction ID string
// Constructor
Transaction(int id, Socket socket) {
this.socket = socket; // Set client socket
this.id = "#" + id + ": "; // Set transaction ID
start(); // Start transaction thread
}
// Echo string from socket input stream to socket output stream
// Incoming data is echoed byte-by-byte without buffering
// End of data is indicated by the end of the input stream (not a newline)
// Thus avoids readLine() (noted in TYJ - pp181) and allows multi-line text
private String echoString(Socket socket) {
DataInputStream in = null; // Input stream
DataOutputStream out = null; // Output stream
String s = ""; // String buffer
try { // Read/write string
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
for (int c; (c = in.read())!=-1; out.write(c)) s += (char)c;
} catch (IOException e) { // Operation failed
s = null;
} finally { // Close i/o streams
try { if (out!=null) out.close(); }
catch (IOException e) { s = null; }
try { if (in!=null) in.close(); }
catch (IOException e) { s = null; }
}
return s; // Echoed-string or null
}
// Execute transaction and report progress
public void run() {
String s;
println(new java.util.Date().toString());
println("Remote IP: " + socket.getInetAddress());
println("Remote Port: " + socket.getPort());
if ((s = echoString(socket))!=null) println("Text Received:\n" + s);
println((s!=null) ? "Transaction complete." : "EchoServer I/O error!");
try { socket.close(); } catch (IOException e) {}
}
// Report a message prefixed with the transaction ID number
private void println(String s) { EchoServer.win.println(id + s); }
}
// Create the server socket and the window and process transactions
public class EchoServer {
static ServerWindow win; // GUI object
static ServerSocket socket; // Server socket object
static int port = 9999, num; // Port and transaction number
private static String info =
"\nIM269 - Coursework 2: EchoServer\nSemester A, 2nd November 1998\n" +
"Eamonn Martin (BSc Computing)\nStudent ID: 96/D59682\nefm001@unl.ac.uk\n\n" +
"EchoServer [port]\n\n" +
"The optional 'port' command-line parameter overrides the default of 9999.\n" +
"The 'Reset' button clears the log and resets the transaction counter.\n\n" +
"A full listing of this program can be found on the World Wide Web at:\n\n" +
"\t\t http://www2.unl.ac.uk/~efm001/im269/\n";
// Create the GUI and the server socket and monitor for clients
public static void main(String[] args) {
System.out.println(info);
if (args.length > 0) try { // Read command-line port?
port = (Integer.decode(args[0])).intValue();
} catch (NumberFormatException e) { // Invalid port number
System.err.println(args[0]+" is not a valid port number!");
return; // Abort program
}
try { socket = new ServerSocket(port); }// Create a server socket
catch (IOException e) { // No socket created
System.err.println("Unable to create socket on port "+port+"!");
return; // Abort program
}
System.out.println("Starting EchoServer...");
win = new ServerWindow("EchoServer"); // Create server window
while (true) { // Wait for connections
try { Socket s = socket.accept();
win.println("\nConnection #" + (++num) + " accepted.");
new Transaction(num, s);// Create a transaction
} catch (IOException e) {}
}
}
}
Go To: IM269: Programming The Internet