客户端似乎在没有服务器接受的情况下已连接

时间:2019-09-13 08:44:04

标签: java sockets

我试图说明套接字服务器和客户端的问题,即该服务器一次只能处理一个客户端,因此多个客户端必须互相等待。

这是我的服务器类。我可以接受来自一个客户端的连接,读取一些字符串,然后将其大写并发回。然后将为下一个客户提供服务。因此,如果我启动多个客户端,则第一个将连接,但其余的将不得不等待服务器再次调用accept()。那是假设。

System.out.println("Starting server...");

try {
    ServerSocket welcomeSocket = new ServerSocket(2910);

    while(true) {
        Socket socket = welcomeSocket.accept();
        System.out.println("client connected");

        ObjectInputStream inFromClient = new ObjectInputStream(socket.getInputStream());
        String o = (String)inFromClient.readObject();
        System.out.println("Received: " + o);

        String answer = o.toUpperCase();

        ObjectOutputStream outToClient = new ObjectOutputStream(socket.getOutputStream());
        System.out.println("Sending back: " + answer);
        outToClient.writeObject(answer);
    }
} catch (IOException | ClassNotFoundException e) {
    // socket stuff went wrong
}

这是我的客户代码:

try {
    Socket socket = new Socket("localhost", 2910);
    System.out.println("Connected to server");
    ObjectOutputStream outToServer = new ObjectOutputStream(socket.getOutputStream());
    Scanner in = new Scanner(System.in);
    System.out.println("What to send?");
    String toSend = in.nextLine();
    System.out.println("Sending " + toSend);
    outToServer.writeObject(toSend);

    ObjectInputStream inFromServer = new ObjectInputStream(socket.getInputStream());
    String o = (String)inFromServer.readObject();

    System.out.println("Received: " + o);
} catch (IOException | ClassNotFoundException e) {}

我创建到服务器的连接,然后从控制台读取。第一个客户端应该成功连接,然后打印出“已连接到服务器”。其他客户端应坚持创建Socket,直到服务器调用accept()。还是我想。

但是我所有的客户端都打印出“已连接到服务器”,我可以在所有客户端的控制台中键入内容,然后将其发送到服务器。然后,服务器仍将一次响应一个客户端。

但是为什么我的客户端代码从我的服务器接受连接之前的初始连接继续进行?在Java 8中似乎是这种情况,但是现在我在使用Java 11。

1 个答案:

答案 0 :(得分:2)

如果要阻止操作系统在调用accept()之前接受多个连接,请将backlog设置为1。

否则,在调用accept()之前,操作系统通常最多接受5个连接。客户端之所以认为已连接,是因为它们确实是在TCP / IP级别连接的。


请参阅文档:

公共 ServerSocket (int 端口,             int 积压)              引发IOException 创建服务器套接字,并将其绑定到具有指定积压的指定本地端口号。端口号0表示通常从临时端口范围自动分配该端口号。然后可以通过调用getLocalPort检索此端口号。 传入连接指示(连接请求)的最大队列长度设置为backlog参数。如果在队列已满时出现连接指示,则拒绝连接。

如果应用程序指定了服务器套接字工厂,则将调用该工厂的createSocketImpl方法来创建实际的套接字实现。否则,将创建一个“普通”套接字。

如果存在安全管理器,则以port参数作为其参数来调用其checkListen方法,以确保允许该操作。这可能会导致SecurityException。 backlog参数是套接字上请求的最大挂起连接数。它的确切语义是特定于实现的。特别地,实现可以施加最大长度或可以选择完全忽略该参数。提供的值应大于0。如果小于或等于0,则将使用特定于实现的默认值。

参数: 端口-端口号,或为0以使用自动分配的端口号。 backlog -请求的最大传入连接队列长度。

相关问题