Почему я получаю отказано в соединении после 1024 соединений? - PullRequest
6 голосов
/ 29 мая 2009

Я тестирую на локальном сервере Linux с сервером и клиентом на одном сервере. Приблизительно после 1024 соединений, в моем коде, где я соединяюсь, я получаю отказ в соединении. Сначала я подумал, что для выбора был предел fd_set_max, равный 1024, и изменил сервер для выполнения опроса вместо выбора, и я до сих пор не могу получить этот номер. Мой ulimit -n установлен на 2048, и я наблюдаю за lsof на сервере, он достигает около 1033 (не уверен, что это точное число) и не работает. Любая помощь очень ценится.

Ответы [ 8 ]

3 голосов
/ 29 мая 2009

Если вы подключаетесь быстрее, чем ваш сервер звонит accept(), очередь ожидающих подключений может быть заполнена. Максимальная длина очереди задается вторым аргументом на сервере listen() или значением sysctl net.core.somaxconn (обычно 128), если оно меньше.

2 голосов
/ 29 мая 2009

Возможно, вы достигли предела вашего процесса для открытых файловых дескрипторов.

Я не уверен, правильно ли я вас понимаю: у вас есть и серверная, и клиентская стороны в одном и том же процессе? Тогда вы будете использовать в два раза больше файловых дескрипторов. Это близко к тому, что вы видите с ulimit. Если это не так, может ли проблема быть на стороне сервера? Возможно, процесс сервера исчерпал дескрипторы и больше не может принимать больше соединений.

Страница man accept упоминает, что вы должны получить возвращаемое значение:

EMFILE
Достигнут лимит для каждого дескриптора открытого файла.

ENFILE
Достигнуто системное ограничение на общее количество открытых файлов.

Какой код ошибки вы получаете? Очевидно, что вы можете добавить только те соединения, которые были успешно _accept_ed, в select или poll .

Я знаю, что вы уже знаете, как проверить ulimit , но другие не могут:

ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 40448
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 4096
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 40448
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
0 голосов
/ 26 января 2011

У меня были те же симптомы. Даже после увеличения ulimit -n я все равно не смог обработать более 1024 входящих соединений ...

Моя проблема заключалась в том, что я использовал select, который не может обрабатывать FD-сокеты выше 1024. Поэтому, когда я увеличил свой лимит, моя проблема фактически изменилась !!! (которую я сначала не заметил ...)

Чтобы помочь кому-либо с подобными проблемами:

Если вы хотите больше 1024 сокетов, вам нужно

  • увеличение ваш лимит для открытых FD (ulimit -n)
  • и вы можете не использовать select () (вместо этого используйте poll ())
0 голосов
/ 01 июня 2010

Я видел комментарий, который вы сделали с оператором close (sock_fd) в процедуре обработки ошибок.

Вы явно закрываете сокеты после их использования - close () или shutdown ().

Я бы не догадался. На самом деле у вас есть 1024+ одновременных активных соединений? Вы должны были бы задействовать pthreads, чтобы сделать это. Это правильно?

0 голосов
/ 01 июня 2009

Итак, после небольшого исследования ... похоже, что мое прослушивание на стороне сервера имеет глубину очереди 20. Я думаю, в этом причина. Кто-нибудь из вас, ребята, тоже считает, что в этом проблема?

Привет

0 голосов
/ 29 мая 2009

Ваше ограничение связано с ограничениями пользователя linux. Если не указано иное, пределы linux - 1024 открытых файла. Чтобы изменить это навсегда, отредактируйте /etc/security/limits.conf и добавьте

user soft nofile 16535 пользователь hard nofile 16535

или с консоли попробуйте

ulimit -n 16535

Привет

0 голосов
/ 29 мая 2009

Извинения за в основном тривиальные вопросы:)
Вы перекомпилировали сервер, когда сказали «изменено на опрос»? Сервер работает под той же учетной записью? Это fork -ing или, может быть, многопоточный сервер? Вы получаете errno == ECONNREFUSED после звонка на connect() на клиенте? Можете ли вы подтвердить, что вы получите RST в ответ на SYN с tcpdump? Используются ли номера портов клиента повторно? Есть ли соединения в состоянии TIME_WAIT?

0 голосов
/ 29 мая 2009

Есть ли опасность, что сервер открывает отдельный файл журнала для каждого соединения, которое он принимает?

Какой верхний предел говорит другая группа на сервере?

В одной программе, которую я смотрел (несколько лет назад), было немного кода, который устанавливал максимальный размер файла в 1 МБ. «Жаль, что когда он был впервые добавлен, он увеличил размер, но с течением времени и ростом ограничений на размер файла позже это привело к уменьшению размера! Есть ли вероятность того, что у сервера аналогичная проблема - он устанавливает максимальное количество открытых файлов на смехотворно большое число, например 1024?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...