Хост А:
tar cf - stuff | dd | nc -N -l 12987
Хост B:
nc a.example.com 12987 | dd | tar tf -
На хосте А dd
печатает свое резюме после tar
завершает. Таким образом, ясно, что tar закрывает канал / файл -> EOF
.
165040 + 0 записей в 165040 + 0 записей из 84500480 байт передано за 25,464802 секунды (3318325 байт / сек)
На обоих хостах nc
счастливо сидит, не выходя. nc(1)
:
-N shutdown(2) the network socket after EOF on the input. Some
servers require this to finish their work.
Таким образом, на хосте A nc
должен был видеть EOF
, закрыл блин сокет и на хосте B nc
должен был увидеть завершение TCP-соединения и должен был закрыть stdout
(stdin
из dd
/tar
).
Как мне сказать nc
закрывать stdout
/ завершить на хосте B и завершить на хосте A.
nc
ошибка?
-D
(отладка) ничего не делает. nc
даже не могу сказать номер его версии ... вздох
Оба хозяина FreeBSD 10.3-РЕЛИЗ-p4, Только IPv4.
Меня тоже озадачило поведение netcat, поэтому я углубился в код. Вот и вся история:
серверы NC (nc -l
) и клиенты выходят только после того, как взаимное соединение было закрыто. То есть, если каждая из сторон отправила ПЛАВНИК пакет другой стороне.
Сервер всегда отправляет FIN
пакет после получения FIN
пакет от клиента. (Если сервер еще не отправил FIN
пакет.)
Клиент отправляет пакет FIN либо:
EOF
на stdin при запуске с аргументом -N
EOF
на stdin, когда сервер уже отправил пакет FINВариант -d
всегда подразумевает EOF
на стандартном вводе.
Вариант -N
всегда подразумевает отправку FIN
после встречи EOF
на стандартном вводе.
Ответ Георга
server$ echo hello | nc -l -N 2000
client$ nc -d localhost 2000
После отправки hello
, сервер встречает EOF
на стандартный ввод и отправляет FIN
из-за -N
.
Клиент получает сообщение и, благодаря -d
, видит EOF
на стандартный ввод и отправляет FIN
, потому что сервер уже отправил FIN
.
Соединение закрывается, и клиент, и сервер выходят.
Клиент инициирует закрытие
server$ echo hello | nc -l 2000
client$ nc -dN localhost 2000
Сервер сохраняет соединение открытым после EOF
на стандартном вводе.
Клиент видит EOF
на стандартный ввод и отправляет FIN
, из-за -N
.
Сервер отправляет FIN
после получения клиентского FIN
.
Соединение закрывается, и клиент, и сервер выходят.
nc
устанавливает двунаправленный подключение. Т.е. он посылает stdin
от хоста B до хоста A, а также желаемый от A до B.
Использовать -d
на хосте B игнорировать stdin
. -N
на хосте A по-прежнему необходимо закрыть TCP
подключение по EOF.
В итоге
Хост А:
tar cf - stuff | dd | nc -N -l 12987
Хост B:
nc -d a.example.com 12987 | dd | tar tf -