13

我正在使用套接字运行一些测试,并且遇到了一些奇怪的行为:服务器套接字将在第 50 个客户端套接字连接到它之后拒绝连接,即使该客户端套接字在下一个打开之前关闭,即使延迟是在连接之间添加。

以下程序是我的实验代码,它在当前状态下不会抛出异常并正常终止。但是,如果数组大小Socket[] clients增加到超过 50,则在第 50 个连接之后尝试连接的任何客户端套接字都会被服务器套接字拒绝。

问题:为什么服务器套接字拒绝套接字连接的计数为 50?

public static void main(String[] args) {
    try (ServerSocket server = new ServerSocket(2123)) {
        Socket[] clients = new Socket[50];
        for (int i = 0; i < clients.length; i++) {
            clients[i] = new Socket("localhost", 2123);
            System.out.printf("Client %2d: " + clients[i] + "%n", i);
            clients[i].close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

我已经运行了测试,其中另外 50 个套接字连接到另一个本地服务器,并且打开和关闭 100 个套接字没有发生问题,所以我推断它的服务器套接字拒绝连接,而不是打开客户端套接字的一些限制,但是我一直无法发现为什么服务器套接字限制为 50 个连接,即使它们没有同时连接。

4

4 回答 4

16

这一切都在JavaDoc中:

传入连接指示(连接请求)的最大队列长度设置为 50。如果在队列已满时连接指示到达,则拒绝连接。

显然你ServerSocket从不接受任何连接,只是听。您必须调用accept()并开始处理连接或增加积压队列大小:

new ServerSocket(port, 100)
于 2012-10-19T20:30:55.287 回答
4

50 是默认值backlog

http://docs.oracle.com/javase/1.4.2/docs/api/java/net/ServerSocket.html#ServerSocket%28int%29

传入连接指示(连接请求)的最大队列长度设置为 50。如果在队列已满时连接指示到达,则拒绝连接。

于 2012-10-19T20:30:28.300 回答
2

根据@TomaszNurkiewicz 的回答,这是一个有效的示例:

import java.net.*;
import java.util.concurrent.atomic.AtomicBoolean;

public class SockTest{
public static void main(String[] args) {
    final AtomicBoolean shouldRun = new AtomicBoolean(true);
    try  {
        final ServerSocket server = new ServerSocket(2123);
        Thread serverThread = new Thread(){
           public void run() {
              try {
                 while(shouldRun.get()) {
                 Socket s = server.accept();
                 s.close();
             Thread.sleep(1);
                }
              } catch(Exception ex) {
                ex.printStackTrace();
              }
           }
        };
        serverThread.start();
        Socket[] clients = new Socket[150];
        for (int i = 0; i < clients.length; i++) {
            clients[i] = new Socket("localhost", 2123);
            System.out.printf("Client %2d: " + clients[i] + "%n", i);
            clients[i].close();
        }
        shouldRun.set(false);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
       shouldRun.set(false);
    }

  }
}
于 2012-10-19T20:57:00.927 回答
0

你可能会看两件事

  1. 服务器不接受连接。
  2. 服务器无法同时满足过多的连接。这可能是由于积压增加(超过 50 个)引起的。尝试在再次连接到服务器之前以毫秒为单位给出一些时间间隔。就像增加连接一样。我通过在运行测试负载时给出一些时间间隔来解决它。
于 2018-01-25T12:23:36.110 回答