BSD nc (netcat) 不会在 EOF 上终止

geo*_*org 6 networking freebsd bsd nc

主持人A:

tar cf -  stuff | dd | nc  -N -l 12987
Run Code Online (Sandbox Code Playgroud)

主持人乙:

nc a.example.com 12987 | dd | tar tf - 
Run Code Online (Sandbox Code Playgroud)

在主机 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.
Run Code Online (Sandbox Code Playgroud)

因此,对主机Anc应该看到EOF,闭合该死插座和主机Bnc应该看到TCP连接终止并且应该已经关闭stdoutstdindd/ tar)。

我如何告诉在主机 B 上nc关闭stdout/终止并在主机 A 上终止

nc 漏洞?

-D(调试)什么都不做。nc连版本号都分不清……

两台主机都是FreeBSD 10.3-RELEASE-p4,仅限 IPv4。

ens*_*ens 9

我也对 netcat 的行为感到困惑,所以我深入研究了代码。这是整个故事:

nc 服务器 ( nc -l) 和客户端仅在相互连接关闭后才退出。也就是说,如果每一方都向另一方发送了一个FIN数据包。

服务器总是FIN在收到FIN来自客户端的数据包后发送数据包。(除非服务器已经发送了一个FIN数据包。)

客户端发送一个 FIN 数据包:

  • 经过EOF对标准输入,当参数运行-N
  • 经过EOF对标准输入,当服务器已经发出一个FIN包

选项-d总是隐含EOF在标准输入上。

Option-N总是意味着FIN在遇到EOFstdin后发送。

交换数据后退出nc进程的方法:

  1. 乔治的回答

    server$ echo hello | nc -l -N 2000
    client$ nc -d localhost 2000
    
    Run Code Online (Sandbox Code Playgroud)

    发送后hello,服务器EOF在 stdin 上遇到FIN由于-N.

    客户端收到消息,由于-dEOF在 stdin 上看到并发送FIN,因为服务器已经发送了FIN

    连接关闭,客户端和服务器都退出。

  2. 客户端发起关闭

    server$ echo hello | nc -l 2000
    client$ nc -dN localhost 2000
    
    Run Code Online (Sandbox Code Playgroud)

    服务器EOF在标准输入后保持连接打开。

    客户端EOF在 stdin 上看到并发送FIN,因为-N.

    服务器FIN收到客户端的FIN.

    连接关闭,客户端和服务器都退出。


geo*_*org 5

nc建立双向连接。即它stdin从主机 B 向主机 A 发送数据,以及从 A 向 B 发送所需的数据。

在主机 B 上使用-d以忽略stdin. -N仍然需要在主机 A 上关闭TCPEOF 上的连接。


总之

主持人甲:

tar cf -  stuff | dd | nc  -N -l 12987
Run Code Online (Sandbox Code Playgroud)

主持人乙:

nc -d a.example.com 12987 | dd | tar tf - 
Run Code Online (Sandbox Code Playgroud)