Ограничение соединения Java ServerSocket?

я запускал несколько тестов с сокетами, и я столкнулся с некоторым странным поведением: ServerSocket откажется от соединений после подключения к нему 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 ответов


Это все JavaDoc:

максимальная длина очереди для индикации входящего соединения (запрос на подключение) установлена в 50. Если индикация соединения поступает, когда очередь заполнена, соединение отклоняется.

видимо ваш ServerSocket никогда не принимает никаких связей, а только слушает. Вы должны либо позвонить accept() и начать обработку соединения или увеличить очередь задела размер:

new ServerSocket(port, 100)

50 значение по умолчанию для backlog

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

максимальная длина очереди для индикации входящего соединения (запрос на подключение) установлена в 50. Если индикация соединения поступает, когда очередь заполнена, соединение отклоняется.


вот пример, который работает в соответствии с ответом @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);
    }

  }
}

две вещи вы можете посмотреть на

  1. сервер не принимает подключения.
  2. сервер не может обслуживать слишком много соединений одновременно. Это может быть вызвано увеличением отставания (более 50). Попробуйте дать некоторый промежуток времени в миллисекундах перед подключением к серверу снова. Например, наращивать связи. Я решил это, дав некоторый промежуток времени, когда я запустил тестовую нагрузку.