I am attempting to write a very simple chat program to test out ServerSockets and Sockets, the code should work, but when the client make a connection to the server it does not move past the accept method. I know they connected because as soon as I close the client window it says it connected and then gives me errors that it cannot communicate with the client.

Server

package network;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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

public class Server {

    private ServerSocket ss;
    private Socket clientSock;
    private BufferedReader read;
    private PrintWriter write;
    private String text = "";
    private JTextArea conversation;
    private String nl = "\n";
    private JTextField messageField;

    public Server(){
        createSocket();
        JFrame f = new JFrame("Server");
        f.getContentPane().setPreferredSize(new Dimension(500,300));
        f.pack();

        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setResizable(false);

        conversation = new JTextArea(50,10);
        conversation.setEditable(false);
        JScrollPane convoPane = new JScrollPane(conversation);

        JPanel bottomLayout = new JPanel();
        JButton sendButton = new JButton ("Send");
        sendButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0) {
                writeMessage();
            }
        });
        messageField = new JTextField (39);
        bottomLayout.add(messageField);
        bottomLayout.add(sendButton);


        f.add(convoPane, BorderLayout.CENTER);
        f.add(bottomLayout, BorderLayout.SOUTH);
        f.setVisible(true);
        connect();
        chatProgram();
    }


    protected void writeMessage() {
        // TODO Auto-generated method stub
        String w = messageField.getText();
        if (w != null){
            //write.write(w);
            text += w + nl;
        }   
    }


    private void chatProgram() {
        // TODO Auto-generated method stub
        while (clientSock.isConnected()){
            read();
            conversation.setText(text);
        }
        closeSockets();
    }


    private void read() {
        // TODO Auto-generated method stub
        try {
            String r = read.readLine();
            if (r != null){
                text += r + nl;
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    private void closeSockets() {
        // TODO Auto-generated method stub
        try {
            read.close();
            write.close();
            ss.close();
            clientSock.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    private void connect() {
        // TODO Auto-generated method stub
        try {
            text += "Waiting for Connection..." + nl;
            conversation.setText(text);
            clientSock = ss.accept();
            text += "Client Connected" + nl;
            write = new PrintWriter(clientSock.getOutputStream(), true);
            read = new BufferedReader(new InputStreamReader(clientSock.getInputStream()));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }       
    }


    private void createSocket() {
        // TODO Auto-generated method stub
        int port = 0;
        while(port == 0){
            try{
                port = Integer.parseInt(JOptionPane.showInputDialog(null, "Enter the Port"));           
            }catch(java.lang.NumberFormatException e){
                JOptionPane.showMessageDialog(null, "Invalid Port Number");
            }   
        }
        try {
            ss = new ServerSocket(port);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    public static void main(String[] args){
        new Server();
    }


}

and the Client

package network;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class Client {

    private Socket sock;
    private JTextArea conversation;
    private JTextField messageField;
    private String text;
    private BufferedReader read;
    private PrintWriter write;
    private String nl = "\n";

    public Client(){
        createSocket();
        JFrame f = new JFrame("Client");
        f.getContentPane().setPreferredSize(new Dimension(500,300));
        f.pack();

        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setResizable(false);

        conversation = new JTextArea(50,10);
        conversation.setEditable(false);
        JScrollPane convoPane = new JScrollPane(conversation);

        JPanel bottomLayout = new JPanel();
        JButton sendButton = new JButton ("Send");
        sendButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0) {
                writeMessage();
            }
        });
        messageField = new JTextField (39);
        bottomLayout.add(messageField);
        bottomLayout.add(sendButton);


        f.add(convoPane, BorderLayout.CENTER);
        f.add(bottomLayout, BorderLayout.SOUTH);
        f.setVisible(true);
        connect();
        chatProgram();

    }

    protected void writeMessage() {
        // TODO Auto-generated method stub
        String t = messageField.getText();
        if (t != null){
            write.write(t);
            text += t + nl;
        }
    }

    private void chatProgram() {
        // TODO Auto-generated method stub
        while(sock.isConnected()){
            try {
                String t = read.readLine();
                if (t != null){
                    text += t + nl;
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            conversation.setText(text);
        }
        closeSockets();
    }

    private void closeSockets() {
        // TODO Auto-generated method stub
        try {
            write.close();
            read.close();
            sock.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }



    private void connect(){
        try {
            write = new PrintWriter(sock.getOutputStream());
            read = new BufferedReader(new InputStreamReader(sock.getInputStream()));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    private void createSocket(){
        String ip = JOptionPane.showInputDialog(null, "Enter the IP Address");
        int port = Integer.parseInt(JOptionPane.showInputDialog("Enter the port"));
        try {
            sock = new Socket(ip, port);
            sock.bind(InetSocketAddress.createUnresolved(ip, port));
            //sock.connect(InetSocketAddress.createUnresolved(ip, port));
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        new Client();

    }

}

What could be creating the problem that I am having?

Thank you for your help.

Edited 3 Years Ago by sirlink99

does not move past the accept method

In fact it does move past the accept method.
The reason why your "Client connected" message is not displayed is because you add it to a String, but you don't append it to your JTextArea.

What could be creating the problem that I am having?

private void chatProgram()
{
    while (clientSock.isConnected()) // [1]
    {
        read(); // [2]
        conversation.setText(text);
    }

    closeSockets();
}

private void read()
{
    try
    {
        String r = read.readLine(); // [3]

        if (r != null)
        {
            text += r + nl;
        }
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

Even though you have the check clientSock.isConnected() in [1], this check will execute before the call read.readLine(); in [3] (via [2]) blocks - waiting for input.
When the client closes, the connection is reset and an exception is thrown from the underlying client socket input stream at the server-side.
This IOException is propagated from [3] and caught by the catch block in your read() method.

On Client line 69: write.write(t); you need to write a newline here too.
You can do this by writing: write.println(t);.

Edited 3 Years Ago by mvmalderen

Thank you for pointing out what I failed to see. If the readLine() waits for an input what would be the most effective way of avoiding the alternating pattern read-write, and allow the program to function more like a chat room?

ps. I do the newline characters when I do the read portion as seen at line 80 and 82 in the client and server code respectively.

If the readLine() waits for an input what would be the most effective way of avoiding the alternating pattern read-write, and allow the program to function more like a chat room?

To do that you need two threads. One loops waiting for the local user's readLine() and sending the input. The other loops waiting for input from the socket and displaying it.

I have attempted an implementation of threads like

private void chatProgram() {
        // TODO Auto-generated method stub
        new Thread(new Runnable(){
            public void run() {
                System.out.println (sock.isConnected());
                while(sock.isConnected()){
                    try {
                        System.out.println("Waiting for text");
                        String t = read.readLine();
                        System.out.println("Text Recieved");
                        if (t != null){
                            text += t + nl;
                            conversation.setText(text);
                        }
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        //e.printStackTrace();
                    }
                }
                closeSockets();
            }
        }).run();
    }

in both client and server for both server and client. I have also added it to the actionPerformed method for the button. As a test I disabled the read option on the server and just tried sending messages to the client, but the messages did not show up. As you can see in the code I added println before and after to make sure it was getting a message, and the "Text Recieved" was not printed out. Why is it not recieving the message? Also I would like to know if the Threads would work the way they are set up.

Thanks for your help.

new Thread(....).start(); to start a new thread. .run() just executes your run method on the existing thread.
Line 17; NEVER comment out the stackTrace or you will never know about your errors.

I commented it out because after I closed either the client or the server it would spam the console with errors that it couldn't read because there was no stream between the two. After I change the .run() to a .start() I still get the same problem with the client not recieving the message from the server.

Sorry man, but I'm leaving now until after Xmas. You really must capture those error messages and fix them before doing anything else. You can redirect System.err and System.out to a file so you can read them later.
Hopefully someone else will be able to help. See you in a few days.

Good luck
J

Edited 3 Years Ago by JamesCherrill

This article has been dead for over six months. Start a new discussion instead.