ホストA:
_tar cf - stuff | dd | nc -N -l 12987
_
ホストB:
_nc a.example.com 12987 | dd | tar tf -
_
ホストAでは、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
はバージョン番号さえもわかりません...sigh
どちらのホストもFreeBSD 10.3-RELEASE-p4、IPv4のみです。
私もnetcatの振る舞いに戸惑い、コードを掘り下げました。これが全体の話です:
ncサーバー(nc -l
)とクライアントは、相互接続が閉じられた後にのみ終了します。つまり、各パーティが [〜#〜] fin [〜#〜] パケットを他のパーティに送信した場合です。
サーバーは、クライアントからFIN
パケットを受信した後、常にFIN
パケットを送信します。 (サーバーがすでにFIN
パケットを送信していない限り)。
クライアントは次のいずれかでFINパケットを送信します。
EOF
の後、引数-N
を指定して実行した場合EOF
の後、サーバーがすでにFINパケットを送信したときオプション-d
は、標準入力で常にEOF
を意味します。
オプション-N
は、stdinでFIN
を検出した後、常にEOF
を送信することを意味します。
ジョージの答え
server$ echo hello | nc -l -N 2000
client$ nc -d localhost 2000
hello
を送信した後、サーバーは標準入力でEOF
を検出し、-N
が原因でFIN
を送信します。
サーバーはすでにEOF
を送信しているため、クライアントはメッセージを受信し、-d
により、stdinでFIN
を確認してFIN
を送信します。
接続が閉じられ、クライアントとサーバーの両方が終了します。
クライアントがクローズを開始
server$ echo hello | nc -l 2000
client$ nc -dN localhost 2000
サーバーはstdinのEOF
の後も接続を開いたままにします。
-N
が原因で、クライアントはstdinでEOF
を確認してFIN
を送信します。
サーバーは、クライアントのFIN
を受信した後、FIN
を送信します。
接続が閉じられ、クライアントとサーバーの両方が終了します。
nc
は双方向接続を確立します。つまりホストBからホストAにstdin
を送信し、必要なものをAからBに送信します。
ホストBで-d
を使用して、stdin
を無視します。 EOFのTCP
接続を閉じるには、ホストAの-N
が引き続き必要です。
要約すれば
ホストA:
tar cf - stuff | dd | nc -N -l 12987
ホストB:
nc -d a.example.com 12987 | dd | tar tf -