Ограничение соединения 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);
}
}
}
две вещи вы можете посмотреть на
- сервер не принимает подключения.
- сервер не может обслуживать слишком много соединений одновременно. Это может быть вызвано увеличением отставания (более 50). Попробуйте дать некоторый промежуток времени в миллисекундах перед подключением к серверу снова. Например, наращивать связи. Я решил это, дав некоторый промежуток времени, когда я запустил тестовую нагрузку.