java套接字地址已经在使用异常

时间:2015-10-28 14:39:41

标签: java sockets

我正在面对一个棘手的java套接字项目问题。这是我的代码: 服务器:

package second.sockets;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class Server implements Runnable {

    public static String HOST = "localhost";
    public static int PORT = 1234;

    private static final int MAX_USERS = 2;
    private static final Server serverInstance = new Server();
    private ServerSocket serverSocket;
    private List<User> users = new ArrayList<>();

    private Server() {
        try {
            if( this.serverSocket == null ) {
                this.serverSocket = new ServerSocket(Server.PORT);
            }
        } catch(IOException e) {
            e.printStackTrace();
            System.err.println("could not initialize ServerSocket on port="+Server.PORT +
                    "["+ e.getMessage() +"]");
        }
    }

    public static Server getInstance() {
        return Server.serverInstance;
    }

    @Override
    public void run() {
        System.out.println("waiting for incoming connections...");
        try {
            while( !Thread.interrupted() ) {
                this.waitForFreeSlots();
                Socket newSocket=null;
                try {
                    newSocket = this.serverSocket.accept();
                    System.out.println("new connection " + newSocket);
                } catch(IOException e) {
                    System.err.println("could not connect");
                }
            }
        } catch(InterruptedException e) {
            System.err.println("server interrupted");
        }
    }

    private synchronized void waitForFreeSlots() throws InterruptedException {
        while( this.users.size() >= Server.MAX_USERS ) {
            this.wait();
        }
    }

    public static int getPORT() {
        return PORT;
    }

    public static void main(String[] args) {

        Server server = Server.getInstance();
        Thread serverThread = new Thread(server);
        serverThread.start();

    }
}

客户端:

package second.sockets;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {

    public static void main(String[] args) {
        Socket socket=null;
        try {
            socket = new Socket(Server.HOST, Server.PORT);
        } catch(UnknownHostException uhe) {
            System.err.println("could not connect to "+Server.HOST+" on port "+Server.PORT+", no such host");
        } catch(IOException ioe) {
            System.err.println("could not connect to "+Server.HOST + " on port "+Server.PORT);
        }
        System.out.println(socket);
    }

}

我运行服务器并且它可以正常运行,但是当我运行客户端时,我得到could not initialize ServerSocket on port=1234[Address already in use: JVM_Bind],它来自第25行的服务器代码。由于服务器是单例,因此没有多个实例的位置,这很奇怪班上的。更重要的是,我甚至没有在客户main功能中触摸它。我不明白,问题出在哪里?感谢。

编辑: 这是堆栈跟踪。它来自Server的构造函数,虽然它是私有的,它在运行Client之后显示。

java.net.BindException: Address already in use: JVM_Bind
    at java.net.DualStackPlainSocketImpl.bind0(Native Method)
    at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106)
    at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:382)
    at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)
    at java.net.ServerSocket.bind(ServerSocket.java:375)
    at java.net.ServerSocket.<init>(ServerSocket.java:237)
    at java.net.ServerSocket.<init>(ServerSocket.java:128)
    at second.sockets.Server.<init>(Server.java:22)
    at second.sockets.Server.<clinit>(Server.java:15)
    at second.sockets.Client.main(Client.java:12)
    could not initialize ServerSocket on port=21234[Address already in use: JVM_Bind]
    Socket[addr=localhost/127.0.0.1,port=21234,localport=53054]

我没有得到这种转变: at second.sockets.Client.main(Client.java:12) - &GT; at second.sockets.Server.<clinit>(Server.java:15)

2 个答案:

答案 0 :(得分:0)

您在异常中看到的内容来自于您在客户端代码中使用Server.HOST和Server.PORT这一事实。这将调用Server类的类初始值设定项。在此初始化程序中,将创建Server类中的所有静态内容。我发现你有一个静态的服务器实例......所以你实际上已经创建了几个服务器实例。

因此,请避免在客户端代码中使用Server.HOST和Server.PORT并直接使用实际值,它将起作用。

通常,当您想要在两个代码实体之间共享内容时,请将它们移动到第三个实体以分离服务器和客户端。然后让服务器和客户端使用该新实体。

答案 1 :(得分:0)

好的,我弄清楚出了什么问题。在此行socket = new Socket(Server.HOST, Server.PORT);中的客户端中,我使用了类Server中的2个变量。当我删除它并粘贴原始值或将变量变为final时,它开始起作用。这是一些狂野的魔法。