【问题标题】:Java ServerSocket connection limit?Java ServerSocket 连接限制?
【发布时间】:2012-10-19 20:26:35
【问题描述】:

我使用套接字运行了一些测试,遇到了一些奇怪的行为:服务器套接字将在第 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 个连接,即使它们没有同时连接。

【问题讨论】:

    标签: java sockets connection serversocket


    【解决方案1】:

    都在JavaDoc:

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

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

    new ServerSocket(port, 100)
    

    【讨论】:

    • 客户端socket关闭时,队列中的连接不会被移除吗?
    • @EJP 是的,但他们为什么不呢?对我来说,关闭的套接字仍然排队等待连接似乎很奇怪。我想服务器套接字无法知道客户端套接字已关闭。
    • @Vulcan 只是在调用 accept() 方法时,连接从队列中删除。抱歉迟到了 3 年的评论
    【解决方案2】:

    50 是backlog 的默认值

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

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

    【讨论】:

    • 不应该是积压的平台依赖?
    【解决方案3】:

    根据@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);
        }
    
      }
    }
    

    【讨论】:

    • 谢谢;在早些时候看到@TomaszNurkiewicz 的回答后,我实际上创建了一个类似的例子,但没有你的那么干净(我忘记了 AtomicBoolean 并制作了我自己的临时类,具有相同的功能哈哈)。 +1
    【解决方案4】:

    你可能会看的两件事

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-21
      • 1970-01-01
      • 2012-10-30
      • 2018-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多