Рассмотрите трехэтапное квитирование TCP. Это объяснено здесь.
Теперь статья выше упоминает, что две стороны могут попытаться соединиться одновременно, и трехэтапное квитирование хорошо работает в этом случае.
Мы можем моделировать эту ситуацию с помощью API сокетов. то, что мы обычно кодируем сокеты использования, является пассивным открытым (сервер) и активное открытое (клиент)?
Можно вызвать одновременное открытие TCP с помощью API сокетов. Как упоминает Николай, это вопрос выполнения следующей последовательности с таким временем, чтобы начальные SYN пересекались друг с другом.
bind addr1, port1
connect addr2, port2
bind addr2, port2
connect addr1, port1
Вот как я добился одновременного открытия, используя один Linux-хост.
Замедляем интерфейс loopback с помощью netem
tc qdisc add dev lo root handle 1:0 netem delay 5sec
Запустите netcat
дважды
netcat -p 3000 127.0.0.1 2000
netcat -p 2000 127.0.0.1 3000
Два процесса netcat соединяются друг с другом, образуя одно TCP-соединение
$ lsof -nP -c netcat -a -i # some columns removed
COMMAND PID NAME
netcat 27911 127.0.0.1:2000->127.0.0.1:3000 (ESTABLISHED)
netcat 27912 127.0.0.1:3000->127.0.0.1:2000 (ESTABLISHED)
Вот что показал tcpdump (вывод отредактирован для ясности)
127.0.0.1.2000 > 127.0.0.1.3000: Flags [S], seq 1139279069
127.0.0.1.3000 > 127.0.0.1.2000: Flags [S], seq 1170088782
127.0.0.1.3000 > 127.0.0.1.2000: Flags [S.], seq 1170088782, ack 1139279070
127.0.0.1.2000 > 127.0.0.1.3000: Flags [S.], seq 1139279069, ack 1170088783
Мы делаем пассивный сервер и активный клиент, потому что это легко понять, [относительно] легко реализовать и легко написать код. Подумайте о магазине и покупателе, мы оказались бы в одной из следующих ситуаций:
Поскольку сервер пассивно ожидает подключения клиентов, легко предсказать, когда может произойти подключение. Никаких предварительных соглашений (кроме адреса сервера и номера порта) не требуется.
Одновременное открытие , с другой стороны, требует тайм-аутов подключения на обеих сторонах, то есть это должно быть тщательно спланировано, чтобы соединение имело место так, чтобы SYN
пересекались «в полете». Это интересный артефакт протокола TCP, но я не вижу в нем практического применения.
Вы, вероятно, можете попробовать смоделировать это, открыв сокет, привязав его к порту (чтобы другая сторона знала, к чему подключиться) и попытавшись подключиться. Обе стороны симметричны. Возможно, можно попробовать это с помощью netcat с опцией -p
. Однако вам придется поторопиться :)