Concurrent Programming In Java – PART FIVE

New And Improved SimpleChatClient

We built the SimpleChatClient near the beginning of this tutorial, which could send outgoing messages to the server but not receive them. Remember? That’s how we ended up on this thread in the first place because we needed a way to do two things. simultaneously: send messages to the server (interact with the GUI) while reading incoming server messages, which are displayed in the scrolling text area.

import java.io.*;
import java.net.*;
import javax.swing.*;
 
import java.awt.*;
import java.awt.event.*;
 
public class SimpleChatClientA {
 
    private String ipAddress;
    private int port;
    private JTextArea incomingMessageArea;
    private JTextField outgoingMessage;
    private PrintWriter writer;
    private BufferedReader reader;
    private Socket socket;
 
    public SimpleChatClientA(String ipAddress, int port){
 
        this.ipAddress = ipAddress;
        this.port = port;
    }
 
    public void drawGUI() {
 
        JFrame frame = new JFrame("Simple Chat Client");
 
        JPanel mainPanel = new JPanel();
 
        incomingMessageArea = new JTextArea(20,30);
        incomingMessageArea.setLineWrap(true);
        incomingMessageArea.setWrapStyleWord(true);
        incomingMessageArea.setEditable(false);
 
        JScrollPane scroller = new JScrollPane(incomingMessageArea);
        scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
 
        outgoingMessage = new JTextField(20);
 
        JButton sendButton = new JButton("Send");
        sendButton.addActionListener(new SendButtonListener());
 
        mainPanel.add(scroller);
        mainPanel.add(outgoingMessage);
        mainPanel.add(sendButton);
 
        setUpNetworking();
 
        Thread readerThread = new Thread(new IncomingMessageReader());
        readerThread.setName("reader-Thread");
        readerThread.start();
 
        frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
        frame.setSize(400,500);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
    } // close go
    private void setUpNetworking() {
 
        try {
 
            socket = new Socket(ipAddress, port);
            InputStreamReader streamReader = new InputStreamReader(socket.getInputStream());
            reader = new BufferedReader(streamReader);
            writer = new PrintWriter(socket.getOutputStream());
            System.out.println("networking established");
 
        } catch(IOException ex) {
 
            ex.printStackTrace();
 
        }
    } // close setUpNetworking
 
    public class SendButtonListener implements ActionListener {
 
        public void actionPerformed(ActionEvent ev) {
 
            try {
   
                writer.println(outgoingMessage.getText());
                writer.flush();
 
            } catch(Exception ex) {
 
                ex.printStackTrace();
 
            }
           
            outgoingMessage.setText("");
            outgoingMessage.requestFocus();
 
            }
           
    } // close SendButtonListener inner class
 
    public class IncomingMessageReader implements Runnable{
       
        public void run() {
            String msg;
            try {
                while ((msg = reader.readLine()) != null) {
                    System.out.println("Message:    " + msg);
                    incomingMessageArea.append(msg + "\n");
                } //end of while loop
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        } //close run method
    } //close inner class
 
    public static void main(String[] args) {
 
        SimpleChatClientA chatClient = new SimpleChatClientA("localhost",5000);
        chatClient.drawGUI();
   
    }
 
} // close outer class

The really really Simple Chat Server

This server code is compatible with both versions of the Chat Client. Every possible disclaimer has been disclaimed here. We removed many parts that would be required to make this a real server in order to keep the code as simple as possible.

To put it another way, it works, but there are a hundred ways to break it.

import java.io.*;
import java.net.*;
import java.util.*;
public class VerySimpleChatServer {
   
    ArrayList clientOutputStreams;
 
    public class ClientHandler implements Runnable {
        BufferedReader reader;
        Socket sock;
 
        public ClientHandler(Socket clientSocket) {
            try {
                sock = clientSocket;
                InputStreamReader isReader = new InputStreamReader(sock.getInputStream());
                reader = new BufferedReader(isReader);
            }catch(IOException ex) {
                ex.printStackTrace();
            }
        } // close constructor
 
        public void run() {
            String message;
            try {  
                while ((message = reader.readLine()) != null) {
                    System.out.println("read " + message);
                    tellEveryone(message);
                } // close while
            } catch(Exception ex) {
                ex.printStackTrace();
            }
        } // close run
    } // close inner class
 
    public static void main (String[] args) {
        new VerySimpleChatServer().go();
    }
 
    public void go() {
        clientOutputStreams = new ArrayList();
        try {  
            ServerSocket serverSock = new ServerSocket(5000);
            while(true) {
                Socket clientSocket = serverSock.accept();
                PrintWriter writer = new PrintWriter(clientSocket.getOutputStream());
                clientOutputStreams.add(writer);
                Thread t = new Thread(new ClientHandler(clientSocket));
                t.start();
                System.out.println("got a connection");
            }
        } catch(Exception ex) {
            ex.printStackTrace();
        }
    } // close go
 
    public void tellEveryone(String message) {
        Iterator it = clientOutputStreams.iterator();
        while(it.hasNext()) {
            try {
                PrintWriter writer = (PrintWriter) it.next();
                writer.println(message);
                writer.flush();
            } catch(Exception ex) {
                ex.printStackTrace();
            }
        } // end while
    } // close tellEveryone
} // close class

To run the chat client, you need two terminals. First, launch this server from one terminal, then launch the client from another terminal.
Share The Tutorial With Your Friends
Twiter
Facebook
LinkedIn
Email
WhatsApp
Skype
Reddit

Check Our Ebook for This Online Course

Advanced topics are covered in this ebook with many practical examples.