TCP-сервер не принимает правильное количество подключений, выданных клиентом, с небольшим объемом ожидания прослушивания - PullRequest
0 голосов
/ 02 декабря 2018

Я написал простую клиентскую программу для выдачи в общей сложности 10000 соединений с использованием 100 потоков за очень небольшую продолжительность.А простая серверная программа с listen backlog, установленным на 20, использует epoll только для того, чтобы принять любое новое соединение и записать общее количество соединений.Я использовал ulimit -n, чтобы убедиться, что он больше, чем 20000, поэтому должно быть достаточно ресурса fd.

Но после того, как серверная программа accept отредактировала как 8800, 9400 (не фиксированных) соединений, она просто перестала принимать любое новое соединение.Клиент использовал блокировку connect для установления соединения, и все эти 10000 вызовов connect вернулись успешно.Затем все зависает, больше нет пакетов (нет повторной передачи), больше нет принятого соединения.

Но как только я закрыл клиентскую программу, серверная программа начала принимать оставшиеся соединения после закрытия некоторых соединений (и в итоге приняла все 10000подключений и закрыл все эти подключения).

Когда я изменил backlog на 100 или более, все 10000 подключений были приняты без каких-либо проблем.(так что это не проблема с ресурсом fd)

Я знаю, что при принятии очереди полно, linux может просто игнорировать входящее ACK трехстороннего рукопожатия, оставляя соединение клиента установленным, но соединение с сервером все еще не установленным, затем разрешитеретрансляционный механизм работы.И в конечном итоге сервер повторно передает SYN/ACK pakcet, клиент отвечает ACK, чтобы восстановить это соединение, если очередь приема сервера доступна.Если в очереди нет свободного места, сервер снова игнорирует ACK.

Но когда я использую wireshark для мониторинга этих повторных передач, я обнаружил, что произошло лишь небольшое количество повторных передач SYN/ACK (например, 100 ~200, намного меньше, чем число потерянных соединений, которое составляет от 500 до 1500), и они передаются повторно один или два раза, все меньше значения, указанного в /proc/sys/net/ipv4/tcp_synack_retries.Я проверил некоторые из этих повторно переданных SYN/ACK пакетов, все из которых получили ACK s от клиента.Но количество ретранслируемых SYN пакетов от клиента было большим.

Итак, каковы основные детали?

Вот мои коды: client server

1 Ответ

0 голосов
/ 04 декабря 2018

Когда задел заполнен и включены файлы cookie SYN, ядро ​​активирует временный режим потока SYN.На этой диаграмме показано, как работают файлы cookie ( источник ):

enter image description here

Когда активирован поток SYN, все ACK, отправленные клиентомбудет сброшенСервер отправил только SYN / ACK и cookie клиенту, таблица кеша cookie будет намного меньше таблицы сокетов, чтобы поддерживать активное соединение.В этом случае на стороне клиента сокет считался установленным, но на стороне сервера ничего не открывалось (полуоткрытое соединение).

Когда клиентское приложение закрывает сокет, пакет FIN с ACKустановленный флаг будет отправлен на сервер с файлом cookie внутри, сервер увидит, что соединение имеет ACK, в этот момент, если резерв не заполнен, сервер попытается восстановить соединение из файла cookie.Если файл cookie действителен (в пределах допустимого туда-обратно), сокет будет добавлен в очередь невыполненных работ и может обрабатываться как обычный сокет.

Это означает, что при активации режима файлов cookie SYN и очереди невыполненных заданийне заполнен, если клиент отправляет некоторые данные на сервер через полуоткрытые сокеты, функция accept () вернет новое соединение с поступлениями.

...