почему клиентские соединения отображаются как установленные, когда соединение еще не принято

Я пытался воспроизвести ситуацию, когда сервер сильно загружен, в статусе должно быть несколько подключений, SYN_SENT как визуализируется через netcat.

я создал серверный сокет и открыл десять подключений от netcat; я предполагал, что они будут отображаться в netstat как SYN_SENT, но затем с tcpdump похоже, что ядро ​​отправляет syn-ack, и клиент отвечает ack, и рукопожатие tcp завершено, и все они УСТАНОВЛЕНЫ.

import java.io.IOException;
import java.net.ServerSocket;

public class Server {

    public static void main(String[] args) throws IOException, InterruptedException {
        ServerSocket ss = new ServerSocket(9999);
        Thread.currentThread().join();
    }
}

поэтому serversocket.accept не играет никакой роли в установлении соединения (решая, следует ли отправлять syn.ack), а ожидает, пока ОС/ядро назначит дескриптор ввода-вывода для этого сокета? Является ли это поведение одинаковым для разных ОС?


person Rag    schedule 01.09.2013    source источник


Ответы (2)


Поскольку соединение установлено. Вызов accept() не является обязательным условием для этого. Система принимает входящие соединения и ставит их в очередь невыполненных работ. Вызов accept() просто удаляет элемент из очереди, блокируя ее, пока она пуста.

person user207421    schedule 01.09.2013
comment
Вызов accept() принимает отставание в качестве параметра. Этот ввод определяет максимальное разрешенное количество незавершенных TCP-соединений. Итак, если вы имеете дело с большим количеством подключений, убедитесь, что вы указали большой лимит невыполненной работы для вызова accept(). Обратите внимание, что у базовой ОС также может быть свой лимит. Например, у Linux есть собственный максимальный лимит подключений (я думаю, 256), поэтому, если вы укажете отставание более 256, тогда Linux не примет это и вместо этого будет использовать максимальное ограничение в 256. - person Manoj Pandey; 01.09.2013
comment
@ManojPandey Вызов listen() принимает невыполненную работу в качестве параметра. Платформа может изменить то, что вы указали, в большую или меньшую сторону, и нет никакого способа узнать, сделала ли она это, или каково действительное значение. Мне кажется, что это должен был быть ответ на вопрос, а не комментарий к этому ответу. - person user207421; 01.09.2013
comment
Что ж, сначала мне понравился ваш ответ (следовательно, я проголосовал за него!), поэтому я подумал, что добавление подробностей об отставании было бы хорошей дополнительной информацией к вашему ответу!. Я согласен, максимальный предел, предоставляемый listen(), может удивить, и как программист, особенно при написании приложений с интенсивным подключением, нужно знать об этом. - person Manoj Pandey; 01.09.2013
comment
это была опечатка: вы правы, это вызов listen(), который принимает отставание, а не accept().. Для соединений, которые сбрасываются из-за ограничения отставания, экономия заключается в том, что TCP предназначен для обработки этого. Когда сервер игнорирует SYN из-за достижения отставания, он просто отбрасывает пакет SYN и не отправляет RST — таким образом, клиент может повторить попытку позже и отправить другой SYN. Надеюсь, к тому времени отставание сократится. - person Manoj Pandey; 01.09.2013
comment
@ManojPandey Это зависит от платформы. Windows отправляет RST, когда отставание заполнено. Unix и Linux ведут себя так, как вы описываете. - person user207421; 01.09.2013

SYN_SENT существует на более низком уровне сетевого стека, чем то, что вы используете здесь. Вы, вероятно, получите лучшие результаты, используя инструмент для создания сетевых пакетов, чтобы подделать нужные вам части соединения.

person Tassos Bassoukos    schedule 01.09.2013