ТЛ; др
Смотрите выводы в самом конце.
преамбула
Я могу объяснить ваши результаты. Я использую Kubuntu, а не Debian, но все же я считаю, что основные моменты являются общими. Чтобы полностью понять, что происходит, полезно проанализировать случай TCP, а затем сравнить с UDP.
Если вы хотите повторить мое исследование, не прекращайте и не убивайте, nc
если я не скажу об этом или оно не прекратится само по себе. Убей, nc
когда я скажу. Это очень важно. Прочитав полный ответ, вы поймете смысл этого.
Этот анализ требует нескольких терминалов (или tmux
, или screen
).
TCP чехол
Сначала избавьтесь от всех предыдущих nc
процессов.
killall nc
Запустите процесс прослушивания:
nc -l 6900
Изучите вывод lsof -i :6900
. Ваш nc
указан как процесс прослушивания там.
Запустите процесс подключения:
nc localhost 6900
Изучите вывод lsof -i :6900
. Два nc
s - это концы установленного соединения.
Поскольку ваш первый nc
не слушает больше, вы можете запустить второй процесс прослушивания:
nc -l 6900
и второй процесс подключения:
nc localhost 6900
Напечатайте что-нибудь в каждой консоли, где nc
работает (не забывайте бить Enterкаждый раз). Вы заметите, что есть два отдельных соединения. Вы можете установить третий, если хотите.
Проверьте еще lsof -i :6900
раз. Хотя два (ранее) прослушивающих nc
используют один и тот же порт 6900
, два соединения не смешиваются, потому что nc
на других концах используются разные порты. Когда пакет приходит в 6900
порт, ядро проверяет этот другой порт и решает, кто из (ранее) прослушивающих nc
должен его получить.
Вы можете запустить дополнительные (непарные) подключения nc
:
nc localhost 6900 || echo fail
и это немедленно провалится.
У вас все еще есть два отдельных соединения. Завершите одну nc
из каждой пары с помощью Ctrl+ Cили Ctrl+, Dи вы заметите, что соответствующие концы также прекратятся. Это потому, что TCP ориентирован на соединение. Когда соединение изящно завершается с любого из его концов, другой конец уведомляется, чтобы он мог соответственно реагировать - в этом случае nc
просто завершается.
Случай UDP
Важный:
killall nc
Выполните следующие команды последовательно, каждая в отдельной консоли. Также проверьте lsof -i :6900
после каждого, чтобы увидеть, что происходит. Команды:
nc -ul 6900 nc -u localhost 6900
Введите что-то в первую очередь («прослушивание») nc
(хит Enter); проверить lsof -i :6900
; наберите что-нибудь во второй nc
(хит Enter); проверьте еще lsof -i :6900
раз и обратите внимание на изменение.
Затем подготовьте другую пару (в отдельных консолях):
nc -ul 6900 nc -u localhost 6900
Передайте несколько строк назад и вперед, чтобы увидеть, работает ли это. Завершите один nc
с Ctrl+ C( Ctrl+ Dне будет работать) и заметьте, что другой nc
(на соответствующем конце) все еще работает. Другая сторона «соединения» не знает, когда «соединение» «прервано». Как вы могли видеть, lsof
он не знает, что «соединение» «установлено», пока данные не начнут течь.
Я приведу здесь несколько слов, потому что UDP не использует соединение, и в этом главное отличие.
Что может быть сложным?
Пока все должно было работать. Пришло время начать объяснять свои предыдущие результаты, когда что-то не работает.
Важный:
killall nc
Подготовьте «прослушивание» nc
:
nc -ul 6900
Проверьте lsof -i :6900
. Вывод будет выглядеть так:
… UDP *:6900
Подготовьте «соединение» nc
:
nc -u localhost 6900
Проверьте lsof -i :6900
. Пример вывода (ваш 54766
может отличаться):
… UDP *:6900 … UDP localhost:54766->localhost:6900
Передайте некоторые данные от второго nc
к первому. Проверьте lsof -i :6900
:
… UDP localhost:6900->localhost:54766 … UDP localhost:54766->localhost:6900
Завершите второе nc
с помощью Ctrl+ C. Еще раз lsof -i :6900
:
… UDP localhost:6900->localhost:54766
Это означает, что первый nc
«общается» только с портом 54766
на другом конце «соединения». Когда вы пытаетесь соединиться с третьим nc
:
nc -u localhost 6900
Скорее всего, он выберет другой случайный порт на своей стороне. Попытайся. Вы сможете "пропустить" (примерно) две строки, как вы это делали в своем вопросе, прежде чем это nc
закончится.
(Примечание: это nc
завершается из-за ICMP-пакета, см. Это ; вы можете захватить пакет, wireshark
как я.)
Однако вы можете принудительно настроить правильный порт (изменить, 54766
чтобы он соответствовал вашему lsof
выводу):
nc -up 54766 localhost 6900
и этот четвертый nc
сможет передавать данные! Первый nc
не увидит разницы. Будет так, как если бы второе nc
никогда не заканчивалось.
Завершите четвертый, nc
прежде чем продолжить. Оставьте первый работающим.
-v
вариант
Последняя загадка: почему nc -v -u localhost 6900
немедленно ушли?
В приведенном выше примере у нас было четыре nc
с:
- первый - «слушающий»;
- вторая - успешно подключена, затем прекращена;
- третий - невозможно подключиться из-за неправильного локального порта;
- четвертый - возможность подключения благодаря правильному (принудительному) локальному порту.
В моем Kubuntu nc -uv …
, если это второй, передает мало X
символов, вероятно, чтобы проверить соединение. По этой причине, если он третий, ему не нужно (около) двух строк внешнего ввода для сбоя, он сразу выходит из строя. После первого nc
запуска попробуйте:
nc -uv localhost 6900
Это должно потерпеть неудачу. Опять же, вы можете принудительно настроить правильный порт, и он будет работать так же, как четвертый nc
в приведенном выше примере.
nc -uvp 54766 localhost 6900
Когда я вызываю это, я вижу X
напечатанные -s в консоли первого nc
.
очищающий
killall nc
Выводы
Мне кажется, что у вас («прослушивание»), nc
который уже был связан с определенным портом на другой стороне «соединения», скорее всего из-за другого nc
(или чего-то еще), который успешно передал хотя бы один пакет. Ваши другие nc
пытались использовать другие порты на своей стороне и не могли связаться с этим первым.
Если я заменю
localhost
с127.0.0.1
, есть прогресс
Ненужные. Я полагаю, в этом случае вы только начали чистить, как мы сделали после killall nc
.