netcat的-q选项到底是做什么的?

时间:2017-01-21 07:14:17

标签: python sockets proxy netcat

我有一个服务,我的行为我一直在代理后面调试。代理是一个黑盒子,但服务的行为可以使用如下的普通python程序进行模拟:

#!/usr/bin/env python

import socket
import sys
import time

PORT = int(sys.argv[1] or 50007)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
    s.bind(('', PORT))
    s.listen(1)
    conn, addr = s.accept()
    print('conn from %s' % (addr,))
    data = conn.recv(1024)
    time.sleep(1)
    conn.sendall(data)
finally:
    conn.close()
    s.close()

当我直接用netcat连接到它时,我得到了预期的行为,即在使用换行符向stdin发送一些任意文本后,服务器会延迟一秒钟,回复它并关闭连接。但是,当我将此服务放在代理后面时,netcat会立即以状态0退出,除非我给它带有一些非零数字的-q选项,之后它的行为与直接连接相同。

引用我系统上netcat的联机帮助页:

-q      after EOF on stdin, wait the specified number of seconds and then quit.
        If seconds is negative, wait forever.

我正在尝试调试的是关于代理连接行为的不同,这会导致连接行为与-q选项不同,不幸的是,手册页没有做很多帮助我。什么是它所指的“stdin”,如果它不是我的输入(它从未收到我的EOF)? EOF是否-q忽略了足够长的时间来接收代理数据,当没有代理调解连接时它不必忽略?

编辑:根据要求,这里有一些示例调用,虽然它们基本上是基本的:

# after starting the example server on <someserver> with <someport

$ echo foo | nc <someserver> <someport>
foo
$

# the above, just with -q1 (no change)
$ echo foo | nc -q1 <someserver> <someport>
foo
$

# after starting the example server behind the blackbox proxy
$ echo foo | nc <someproxy> <someproxyport>
$

# same, but with -q
$ echo foo | nc -q1 <someproxy> <someproxyport>
foo
$

1 个答案:

答案 0 :(得分:5)

echo foo | netcat在所有情况下都会发送EOF。不同之处在于netcat关闭其网络套接字的方式。

没有-q netcat在收到EOF后立即发送TCP FIN,关闭其一半的TCP连接。这不是一个完整的连接关闭,只是an indication不再发送数据。之后netcat保持从连接打印数据,直到它关闭。

普通服务器不处理来自netcat的FIN,延迟,发送回应响应,然后关闭连接的后半部分。

blackbox代理似乎通过立即关闭连接来对客户端的FIN作出反应。这可能是某种服务器负载优化,例如,在许多Web浏览器的情况下都有这种感觉。

使用-q netcat在服务器关闭连接或-q超时结束之前不发送FIN。

tcpdump -w下运行您的四个案例,然后在Wireshark中加载捕获文件,按照TCP流并查看差异。请注意,此netcat行为可能取决于particular version,我确认它适用于Ubuntu 16.04 + netcat-openbsd 1.105。