BindException:即使使用唯一端口,地址也已在使用中

时间:2014-04-27 22:00:39

标签: java linux eclipse sockets port

我昨天问了这个问题,没有人能够弄清楚我遇到的问题。所以我希望提供一个更新的代码,其中包含昨天添加的建议。基本上,我一直试图在服务器和客户端之间建立连接,但每当我执行服务器然后客户端时,我都会得到这个例外:Address already in use。显而易见的答案是给它一个新的端口,但即使这样我仍然会得到这个错误。我假设它与我的代码出错有什么关系。有人能发现它吗?我已经附加了服务器类和客户端类。

这是我得到的错误:

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)

服务器代码:

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);
        }
    }
}

客户代码:

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) { }
    }
}

3 个答案:

答案 0 :(得分:5)

当服务器程序尝试在端口53705上打开套接字进行侦听时,您将收到错误消息。 Address already in use消息就是这样,你机器上的另一个进程已经在使用端口53705.可能是某个守护程序进程巧合地打开了这个端口,或者你的Web浏览器已经打开了这个端口并且仍在使用它

但最有可能的是,您的服务器程序的另一个实例在后台运行。检查所有终端窗口,或检查IDE以查看包含正在运行的程序状态的选项卡。

顺便说一句,“唯一端口”有点误导,因为端口53705在任何方面都不是“唯一”,它恰好是你(或某人)选择的希望<的端口号/ strong>尚未使用。要获得真正唯一的端口,请使用new ServerSocket(0),它将要求系统分配未使用的端口。要找出分配的端口,请使用serverSocket.getLocalPort()。您可以将其打印出来,然后将其作为命令行选项传递给客户端程序。

答案 1 :(得分:1)

我认为你正在遇到一个平台和java的特定问题。 请提供有关您的os平台(x86 / x64)以及您使用哪个供应商的jdk版本的其他信息?

根据此链接 http://www.oracle.com/technetwork/java/javase/7u51-relnotes-2085002.html 以上Oracle JDK 7u51:分配给包括不受信任代码在内的所有代码的默认套接字权限已更改。您只能将套接字绑定到每个系统上的临时端口范围。 端口 53705 应该是一个保存短暂端口。 但仍然使用

netstat -an | grep 53705 

仔细检查端口是否在linux中使用,并使用netstat或tcpview for windows。 你可以使用

less /proc/sys/net/ipv4/ip_local_port_range

让linux检查你的短暂端口范围为linux并找到

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
在windows中

来确定你的短暂端口范围。有关Windows中短暂范围的更多信息,请参阅how to change/view ephemeral port range in windows machines

我可以在没有&#34; man&#34;的情况下确认您的服务器代码和客户端。 - &GT; &#34;主&#34;在使用

的Opensuse 12.3下运行拼写错误
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

答案 2 :(得分:0)

我测试了你的代码并且它正常工作(意思是:我可以连接到服务器,没有测试其余部分)。只需注意MessageSendClient中的主要方法,就会出现拼写错误(&#34; man&#34;而不是&#34; main&#34;),正确的签名是:

public static void main(String[] args)

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

通过执行(用数字替换YOUR_PORT)确保侦听端口空闲

netstat -tulpn | grep :YOUR_PORT

因为那就是你得到那个例外的原因。如果你在Windows上,你可能只是运行

netstat -an

并搜索端口。