4

I know this question has been asked a million times but I haven't found a situation like mine. I have a simple chat application in java that was working a few months ago and I've come back to it and now I'm having problems. When I run my server.java in eclipse, everything works fine. When I run the client.java file afterwards, I get the following:

Exception in thread "main" java.net.BindException: Address already in use: NET_Bind
    at java.base/java.net.DualStackPlainSocketImpl.bind0(Native Method)
    at java.base/java.net.DualStackPlainSocketImpl.socketBind(Unknown Source)
    at java.base/java.net.AbstractPlainSocketImpl.bind(Unknown Source)
    at java.base/java.net.PlainSocketImpl.bind(Unknown Source)
    at java.base/java.net.ServerSocket.bind(Unknown Source)
    at java.base/java.net.ServerSocket.<init>(Unknown Source)
    at java.base/java.net.ServerSocket.<init>(Unknown Source)
    at chat.Server.main(Server.java:18)

I've terminated all launches in eclipse, found the PID in command prompt and killed it, tried changing the port numbers, and I still get the address still in use every time I try to run my programs. I've also tried running the netstat -a command in command prompt to find the port numbers in use, none of which have been ones I've tried.

Server.java(contains server code as well as a client handler class):

public class Server 
{
    //vector to store active clients, static so threads share the vector of clients
    static Vector<ClientHandler> activeUsers = new Vector<>();

    public static void main(String[] args) throws IOException 
    {
        ServerSocket serverSocket = new ServerSocket(1234); //server is listening on port 1234
        Socket s;   
        while (true) //infinite loop for getting client request
        {
            s = serverSocket.accept(); //accept the incoming request

            //obtain input and output streams
            DataInputStream dis = new DataInputStream(s.getInputStream());
            DataOutputStream dos = new DataOutputStream(s.getOutputStream());

            String username = dis.readUTF(); //username is first thing sent from the client for naming
            ClientHandler newClient = new ClientHandler(s,username , dis, dos); //create a new handler object for handling this client

            //notify currently connected users that a new user has joined
            newClient.notifyUsers(activeUsers, " has joined the server!");

            Thread t = new Thread(newClient); //create a new Thread with this object.
            activeUsers.add(newClient); //add this client to active clients list
            t.start(); //start the thread.
        }//end while


    }//end main
}//end class Server

class ClientHandler implements Runnable 
{
    private String name;
    DataInputStream dis;
    DataOutputStream dos;
    Socket socket;
    boolean isloggedin;


    public ClientHandler(Socket socket, String name, DataInputStream dis, DataOutputStream dos) 
    {
        this.dis = dis; //data input stream
        this.dos = dos; //data output stream
        this.name = name; //client name
        this.socket = socket; //socket
        this.isloggedin=true; //handler is being created so user is logged in
    }
}

Client.java:

public class Client extends JFrame implements ActionListener
{
    DataInputStream dis = null;
    DataOutputStream dos = null;
    final static int ServerPort = 1234;
    JButton     sendMessage;
    JTextField  messageBox;
    JTextArea   chatBox;
    JButton     logoutButton;
    JButton     activeUsersButton;
    JFrame      newFrame    = new JFrame(".Chat");
    String username;
    Socket s = null;


    public Client(String user)
    {

        this.username = user;
    }

    public void start() throws UnknownHostException, IOException 
    {
        newFrame.setTitle("chat - " + username);

        InetAddress ip = InetAddress.getByName("localhost");

        //establish the connection to the server
        s = new Socket(ip, ServerPort);

        //obtaining input and out streams
        dis = new DataInputStream(s.getInputStream());
        dos =  new DataOutputStream(s.getOutputStream());

        dos.writeUTF(username);

        //readMessage thread
        Thread readMessage = new Thread(new Runnable() 
        {
            @Override
            public void run() 
            {
                while (dos != null && dis != null) {
                    try 
                    {
                        //read the message sent to this client
                        String msg = dis.readUTF();
                        System.out.println(msg);
                        chatBox.append(msg);
                    } //end try
                    catch (IOException e) 
                    {

                        e.printStackTrace();
                    }//end catch
                }//end while
            }//end run
        });
        display();
        readMessage.start();
    }


    //not sure what this needs to do? just to satisfy an error
    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
         Object obj = e.getSource();
           if(obj == sendMessage){ 
                String msg = messageBox.getText();
                try {
                    dos.writeUTF(msg);
                    chatBox.append(username + ": " + msg + "\n"); //place what the user sent in the text box
                    messageBox.setText(""); 
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
           } 
           else{}
    }
}

I've left out the button code as its only sending/receiving messages on the sockets as well as the UI code.

7
  • The problem is that when you run the Client it connects to the server and then your server application tries to create a second socket on the same port and gets the error. Try moving Socket s; inside the loop? Commented Jul 6, 2018 at 7:17
  • @Veselin Davidov, just tried that and still getting the same error. The Socket S in the server file is the client's socket that is connecting to the Server and is stored in the ClientHandler object, I'm not creating a new one. This was all working and I hadn't changed anything so I'm kind of just at a stand still at the moment. Commented Jul 6, 2018 at 7:26
  • On Linux, you can use netstat, lsof or nmap to find out what ports are in use. Commented Jul 6, 2018 at 7:35
  • @StephenC sorry, edited to add that I was running the netstat -a command in command prompt to find the currently used ports, and none of the ports I was trying were actually in use before running. Commented Jul 6, 2018 at 7:42
  • @VeselinDavidov What are you talking about? Have you read the stack trace? Commented Jul 6, 2018 at 8:13

1 Answer 1

2

Something is already listening at port 1234 when you start your server: possibly a prior instance of it; or possibly there is still a socket in TIME_WAIT. Try it with SO_REUSEADDR, this way:

ServerSocket serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress(1234));

NB You have another problem. You are ignoring end of stream. Given that you're calling readUTF(), you need to catch EOFException and exit the loop and close the socket when it is thrown. EOS doesn't magically make the input or output streams null.

Sign up to request clarification or add additional context in comments.

6 Comments

He said he checked for prior instances of the software and killed all. He also said that he gets the problem when he runs the Client and not the server - the server runs fine initially. That's why I suspect the problem rises when he tries to open the Socket for the second time - AFTER the client he just started has connected.
@VeselinDavidov So why doesn't accept() appear in the stack trace? And why is it that the ServerSocket constructor does appear? And what is this nonsense about opening a socket for the second time? You seem to be suggesting that he shouldn't be calling. accept() at all.
@EJP - Sorry for the late response. Just changed my server socket creation to your suggestion and still receiving the same error. Did you mean making the socket and not the server socket null? I'm handling that in the ClientHandler when a logout event is received, just didn't include that part of the code.
I didn't mean making anything null. I meant closing the socket, or the input stream, or best of all the output stream.
@EJP I'm closing them in the client handler class when a user logs out, but I'm not making it passed binding the socket in the Server.java file. The address already in use error occurs when I try to run the client file after the server file is already running.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.