Host A:
tar cf - stuff | dd | nc -N -l 12987
Host B:
nc a.example.com 12987 | dd | tar tf -
On host A dd
prints its summary after tar
completes. Thus it is clear, that tar closes the pipe/file -> EOF
.
165040+0 records in 165040+0 records out 84500480 bytes transferred in 25.464802 secs (3318325 bytes/sec)
On both hosts nc
happily sits there without exiting.
nc(1)
:
-N shutdown(2) the network socket after EOF on the input. Some
servers require this to finish their work.
Thus on host A nc
should have seen EOF
, closed the damn socket and on host B nc
should have seen the TCP connection terminate and should have closed stdout
(stdin
of dd
/tar
).
How do I tell nc
to close stdout
/ terminate on host B and terminate on host A.
nc
bug?
-D
(debug) does nothing. nc
can't even tell its version number... sigh
Both hosts are FreeBSD 10.3-RELEASE-p4, IPv4 only.
I, too, was puzzled by netcat's behavior, so I dug into the code. Here's the whole story:
nc servers (
nc -l
) and clients only exit after the mutual connection was closed. That is, if each of the parties sent a FIN packet to the other party.A server always sends a
FIN
packet after receiving aFIN
packet from the client. (Unless the server already sent aFIN
packet.)A client sends a FIN packet either:
EOF
on stdin, when run with argument-N
EOF
on stdin, when the server already sent a FIN packetWith option
-d
stdin is ignored andnc
behaves as if it encounteredEOF
on stdin.Option
-N
always implies sendingFIN
after encounteringEOF
on stdin.Ways to exit the nc processes after exchanging data:
Georg's answer
After sending
hello
, the server encountersEOF
on stdin an sendsFIN
because of-N
.The client receives the message and, due to
-d
, seesEOF
on stdin and sendsFIN
, because the server already sentFIN
.The connection is closed, both the client and the server exit.
Client initiates the close
The server keeps the connection open after
EOF
on stdin.The client sees
EOF
on stdin and sendsFIN
, because of-N
.The server sends
FIN
after receiving the client'sFIN
.The connection is closed, both the client and the server exit.
nc
establishes a bi-directional connection. I.e. it sendsstdin
from host B to host A as well as the desired one from A to B.Use
-d
on host B to ignorestdin
.-N
on host A is still needed to close theTCP
connection on EOF.In summary
Host A:
Host B: