Recent Changes - Search:

Distributed Computing

This website demonstrates using wikis as teaching and learning tool.

The course instructor is also happy to share the teaching materials here with those who find it readable.

Client-side networking with Java stream socket

Introduction

You will complete a TCP client program (called POPClient) to experience how to communicate with a POP server, how to obtain information about emails, and how to instruct the POP server to delete certain emails.

The following shows you a snapshot of the intended program of POPClient. The program has several TextField objects for users to enter the connection information such as host name, port number, username and password. It also has a TextField for users to enter textual message and send it to the connected server. Finally, the program has two TextArea objects. One is for printing the messages received from the server, and another is to log down any messages sent to the server.

The GUI part of the program has been designed and implemented for you. You can get it and test it yourself.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

public class POPClient extends JFrame implements ActionListener, Runnable {

    protected JTextField textFieldHost;
    protected JTextField textFieldPort;
    protected JTextField textFieldUser;
    protected JPasswordField passwordField;
    protected JTextField textFieldInput;
    protected JButton connectButton;
    protected JButton exitButton;
    protected JTextArea clientTextArea;
    protected JTextArea serverTextArea;

    protected Socket socket = null;
    protected BufferedReader in = null;
    protected PrintWriter out = null;
    protected Thread recvThread = null;
    protected String line = null;

    // Constructor for setting up GUI
    public POPClient() {
        // please replace S0612345 with your student ID number ***
        super("POP Client (COMPS368F Coursework by S0612345)");

        textFieldHost = new JTextField(15);
        textFieldPort = new JTextField(15);
        textFieldUser = new JTextField(15);
        passwordField = new JPasswordField(15);
        connectButton = new JButton("Connect");
        exitButton = new JButton("Exit");
        textFieldInput = new JTextField(20);
        connectButton.addActionListener(this);
        exitButton.addActionListener(this);
        textFieldInput.addActionListener(this);
        clientTextArea = new JTextArea();
        clientTextArea.setLineWrap(true);
        clientTextArea.setWrapStyleWord(true);
        clientTextArea.setEditable(false);
        clientTextArea.setBackground(new Color(80,0,0));
        clientTextArea.setForeground(Color.white);
        serverTextArea = new JTextArea();
        serverTextArea.setLineWrap(false);
        serverTextArea.setWrapStyleWord(false);
        serverTextArea.setEditable(false);
        serverTextArea.setBackground(new Color(0,0,80));
        serverTextArea.setForeground(Color.white);
        JLabel labelHost = new JLabel("Host Name: ");
        JLabel labelPort = new JLabel("Port Number: ");
        JLabel labelUser = new JLabel("Login User: ");
        JLabel labelPassword = new JLabel("Password: ");
        JPanel connectInfoPane = new JPanel();
        JLabel[] labels = {labelHost,labelPort,labelUser,labelPassword};
        JTextField[] textFields = {
            textFieldHost,textFieldPort,textFieldUser,passwordField };
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();
        connectInfoPane.setLayout(gridbag);
        c.anchor = GridBagConstraints.EAST;

        int numLabels = labels.length;
        for (int i = 0; i < numLabels; i++) {
            c.gridwidth = GridBagConstraints.RELATIVE;
            c.fill = GridBagConstraints.NONE;
            c.weightx = 0.0;
            gridbag.setConstraints(labels[i], c);
            connectInfoPane.add(labels[i]);
            c.gridwidth = GridBagConstraints.REMAINDER;
            c.fill = GridBagConstraints.HORIZONTAL;
            c.weightx = 1.0;
            gridbag.setConstraints(textFields[i], c);
            connectInfoPane.add(textFields[i]);
        }

        connectInfoPane.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createTitledBorder("Connection Info"),
            BorderFactory.createEmptyBorder(5,5,5,5)));

        JScrollPane clientAreaScrollPane = new JScrollPane(clientTextArea);
        clientAreaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        clientAreaScrollPane.setPreferredSize(new Dimension(300, 250));

        clientAreaScrollPane.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createCompoundBorder(
            BorderFactory.createTitledBorder("Client Request Log"),
            BorderFactory.createEmptyBorder(5,5,5,5)),
            clientAreaScrollPane.getBorder()));

        JScrollPane serverAreaScrollPane = new JScrollPane(serverTextArea);
        serverAreaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        serverAreaScrollPane.setPreferredSize(new Dimension(450, 400));
        serverAreaScrollPane.setBorder(
            BorderFactory.createCompoundBorder(
            BorderFactory.createCompoundBorder(
            BorderFactory.createTitledBorder("Server Response Log"),
            BorderFactory.createEmptyBorder(5,5,5,5)),
            serverAreaScrollPane.getBorder()));

        JPanel inputPane = new JPanel();
        gridbag = new GridBagLayout();
        c = new GridBagConstraints();
        inputPane.setLayout(gridbag);
        c.fill = GridBagConstraints.BOTH;
        c.weightx = 1.0;
        gridbag.setConstraints(connectButton, c);
        inputPane.add(connectButton);
        c.gridwidth = GridBagConstraints.REMAINDER;
        gridbag.setConstraints(exitButton, c);
        inputPane.add(exitButton);
        c.weightx = 0.0;
        c.gridwidth = GridBagConstraints.REMAINDER;
        c.fill = GridBagConstraints.BOTH;
        gridbag.setConstraints(textFieldInput, c);
        inputPane.add(textFieldInput);

        inputPane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createTitledBorder("Action Input"),
            BorderFactory.createEmptyBorder(5,5,5,5)),

        inputPane.getBorder()));
        JPanel leftPane = new JPanel();
        BoxLayout leftBox = new BoxLayout(leftPane, BoxLayout.Y_AXIS);
        leftPane.setLayout(leftBox);
        leftPane.add(connectInfoPane);
        leftPane.add(inputPane);
        leftPane.add(clientAreaScrollPane);
        JPanel contentPane = new JPanel();
        BoxLayout box = new BoxLayout(contentPane, BoxLayout.X_AXIS);
        contentPane.setLayout(box);
        contentPane.add(leftPane);
        contentPane.add(serverAreaScrollPane);
        setContentPane(contentPane);
    }

    private void connect() {
    // This method is invoked when user press the Connect button.
    // You need to write code here for part (b)
    }

    private void closeAndExit() throws IOException {
    // This method is invoked when user press the Exit button.
        if (out != null) {
            out.print("quit\n");
            out.flush();
        }
        if (in != null) {
            while  ( (line = in.readLine()) != null) {
                serverTextArea.append(line);
                serverTextArea.append("\n");
            }
        }

        if (recvThread != null) recvThread=null;
        if (socket != null) socket.close();
        System.exit(0);
    }

    private void sendCommand(String input) {
    // This method is invoked when user press enter in textfield.
    // You need to write code here for part (c)
    }

    public void actionPerformed(ActionEvent e) {
    // Handling event when user press the button
    // or press enter in the input text field.
    // You need to write code here for part (a)
    }

    public void run() {
    // This is a thread for receiving server messages.
    // You need to write code here for part (d)
    }

    public static void main(String[] args) {
        JFrame frame = new POPClient();
        frame.addWindowListener(
            new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }
            });
        frame.pack();
        frame.setVisible(true);
    }
}

Your Tasks

Please get the above Java source first. Then compile and execute it to see if it works as expected.

Then, study the source code to get an idea on the structure of the program.

Your task is to complete the program of POPClient by implementing several methods. The following details the specification of them.

Part (a): the method actionPerformed

  1. When the user presses the Connect button, it invokes the connect() method and create a thread where the code is specified in the run() method.
  2. When the user presses enter in the input text field, it invokes the sendCommand() method, and then clear the content of the text field.
  3. When the user presses the Exit button, it invokes the closeAndExit() method.

Part (b): the method connect

  1. Get connection information from various text fields.
  2. Handle the connection information and prompt the user when the typed information is incomplete or incorrect.
  3. Make a TCP connection to the specified server.
  4. Do exception handling for the TCP connection.
  5. On the start of each session of TCP connection, clear the two text areas (serverTextArea and clientTextArea).

Part (c): the method sendCommand

  1. Send the request message to the server.
  2. Output the message to the client text area for logging.

Part (d): the method run

This is the code for continuously receiving the messages from the server and outputting them to the server text area. Your code should also handle any exception that will occur.

Testing of your program

By completing parts (a) to (d), you have a POP client (with proper GUI) to talk to a POP server. If you don't know much about the POP, study the following basic commands of POP.

LIST
See a list of your emails awaiting collection. Also show you the id number of your messages (e.g. 1 or 2 etc.).
RETR
To view the contents of an email, type RETR + the id number of the message (e.g RETR 1).
DELE
To delete a message, type DELE + the id number of the message (e.g DELE 1).
STAT
Show you the total number and total size of your messages.
TOP
To view the header of an email, type TOP + the id number of the message + the number of lines (e.g. TOP 1 10).
QUIT
Leave your mailbox and close the connection.

Course Requirement and Assessment

You need to demonstrate your work to your instructor in a tutorial session. Your instructor may ask you some questions to test your knowledge.

This programming task is a part of your continuous assessment. The maximum point awarded is 20. The assessment is roughly based on the following criteria:

  1. Implementation of the method actionPerformed. (5 points)
  2. Implementation of the method connect. (8 points)
  3. Implementation of the method sendCommand. (3 points)
  4. Implementation of the method run. (4 points)
Edit - History - Print - Recent Changes - Search
Page last modified on September 27, 2007, at 11:40 PM