BindException: Address already in use even with un

2019-06-25 23:04发布

问题:

I've asked this question yesterday and no one was able to figure out the problem I was having. So I was hoping of providing a more up to date code with the suggestions from yesterday added on. Basically, I've been trying to form a connection between a server and a client but whenever I executed the server then the client, I'd get this exception: Address already in use. The obvious answer would be to give it a new port, but even then I still get this error. I'm assuming it has something to do with my code somewhere going wrong. Can anyone spot it please? I have attached the server class and the client class.

This is the error I get:

Exception in thread "main" java.net.BindException: Address already in use
    at java.net.PlainSocketImpl.socketBind(Native Method)
    at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:376)
    at java.net.ServerSocket.bind(ServerSocket.java:376)
    at java.net.ServerSocket.<init>(ServerSocket.java:237)
    at java.net.ServerSocket.<init>(ServerSocket.java:128)
    at MessageServer.main(MessageServer.java:16)

Server code:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;

public class MessageServer {

    public static void main(String[] args) throws IOException {
        try {
            int port = 53705;

            ServerSocket server = new ServerSocket(port);

            while (true) {
                System.out.println("Waiting for client...");
                //server.setReuseAddress(true);
                Socket client = server.accept();

                System.out.println("Client from " + server.getInetAddress() + " connected.");
                BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
                String inputLine = in.readLine();
                System.out.println("Client said: '"+inputLine+"'");
                Writer count = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
                byte c [] = count.toString().getBytes();
                count.flush();
                count.close();
                in.close();
            } 
        } catch (IOException e) {
            System.err.println(e);
        }
    }
}

Client code:

import java.net.*;
import java.io.*;

public class MessageSendClient {

    public static void man(String args[]) throws IOException {
        String servername = "localhost";
        int port = 53705;
        Socket server;
        //server.setReuseAddress(true);
        try {
            server = new Socket (servername,port);

            System.out.println("Connected to " + server.getInetAddress());
            DataInputStream in = new DataInputStream(new BufferedInputStream(server.getInputStream()));

            server.close();
            byte c[] = new byte[100];
            int num = in.read(c);
            String count = new String(c);

            System.out.println("Server said: " + count);

        } catch (Exception e) { }
    }
}

回答1:

You're getting the error when the server program attempts to open up a socket on port 53705 for listening. The Address already in use message means just that, another process on your machine is already using port 53705. It could be that some daemon process has opened this same port by coincidence, or your web browser has opened this port and is still using it.

Most likely, though, is that you have another instance of your server program running somewhere in the background. Check all your terminal windows, or check your IDE for tabs containing the status of running programs.

By the way, "unique port" is a bit misleading, as port 53705 isn't "unique" in any way, it just happens to be a port number you (or somebody) picked that you hope isn't already in use. To get a truly unique port, use new ServerSocket(0) which will ask the system to allocate an unused port. To find out which port was assigned, use serverSocket.getLocalPort(). You might print it out, and then pass it to the client program as a command-line option.



回答2:

I think you are running into a plattform and java liberary specific issue. Please provide additional infos about your os plattform (x86/x64) and which version of jdk from which vendor are you using?

According to this Link http://www.oracle.com/technetwork/java/javase/7u51-relnotes-2085002.html Above Oracle JDK 7u51: The default socket permissions assigned to all code including untrusted code have been changed. You can only bind sockets to the ephemeral port range on each system. Port 53705 should be a save ephemeral port. But still use

netstat -an | grep 53705 

to double check if the port is used in linux and use netstat or tcpview for windows. You can use

less /proc/sys/net/ipv4/ip_local_port_range

for linux to check your ephemeral port range for linux and find

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

in windows to get determine your ephemeral port range. More about ephemeral range in windows can be found in how to change/view ephemeral port range in windows machines

I can confirm your server code and client without the "man" -> "main" typo is running under Opensuse 12.3 with

Java version "1.7.0_51"
OpenJDK Runtime Environment (IcedTea 2.4.4) (suse-8.32.5-i386)
OpenJDK Client VM (build 24.45-b08, mixed mode)
jvm is running by an non admin user with groups: www,dialout,video,shadow,users


回答3:

I tested your code and it works correctly (meaning: I can connect to the server, didn't test the rest). Just pay attention to the main method in MessageSendClient, there's a typo ("man" instead of "main") and the correct signature is:

public static void main(String[] args)

not

public static void main(String args[]) // Still compatible but not recommended (C-like syntax)

Make sure the listening port is free by executing (replace YOUR_PORT with the number)

netstat -tulpn | grep :YOUR_PORT

because that's the reason why you get that exception. If you're on Windows you might just run

netstat -an

and search for the port.