BSD nc (netcat) не заканчивается на EOF
Хост А:
tar cf - stuff | dd | nc -N -l 12987
Хост Б:
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-RELEASE-p4, IPv4.
2 ответа
Я тоже был озадачен поведением netcat, поэтому копался в коде. Вот и вся история:
nc серверы (nc -l) и клиенты выходят только после того, как взаимное соединение было закрыто. То есть, если каждая из сторон отправила пакет FIN другой стороне.
Сервер всегда отправляет FIN пакет после получения FIN пакет от клиента. (Если сервер уже не отправил FIN пакет.)
Клиент отправляет пакет FIN либо:
- после
EOFна стандартный ввод, когда запускается с аргументом-N - после
EOFна стандартный ввод, когда сервер уже отправил пакет FIN
вариант -d всегда подразумевает EOF на стандартном
вариант -N всегда подразумевает отправку FIN после встречи EOF на стандартном
Способы выхода из процессов nc после обмена данными:
Георг ответ
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 на хосте А все еще необходимо закрыть TCP подключение по EOF.
В итоге
Хост А:
tar cf - stuff | dd | nc -N -l 12987
Хост Б:
nc -d a.example.com 12987 | dd | tar tf -