为什么在这个 Twisted 示例中 telnet 有效而 netcat 失败?

Why does telnet work and netcat fail with this Twisted example?

我正在关注 Twisted tutorial 并尝试了该文章中的以下代码:

# Read username, output from non-empty factory, drop connections

from twisted.internet import protocol, reactor
from twisted.protocols import basic

class FingerProtocol(basic.LineReceiver):
    def lineReceived(self, user):
        self.transport.write(self.factory.getUser(user)+"\r\n")
        self.transport.loseConnection()

class FingerFactory(protocol.ServerFactory):
    protocol = FingerProtocol

    def __init__(self, **kwargs):
        self.users = kwargs

    def getUser(self, user):
        return self.users.get(user, "No such user")

reactor.listenTCP(1079, FingerFactory(moshez='Happy and well'))
reactor.run()

我试过 nc localhost 1079 但它只是挂起:没有回复。但是 telnet localhost 1079 工作得很好。为什么?

使用 wireshark,我发现了以下内容:telnet 发送 0x0d,然后发送 0x0a(即“\r\n”)作为行终止符。然而 netcat 只发送了 0x0a。这是在 Ubuntu 上(也在 OS X 上)。

显然,Twisted 中的 LineReceiver 协议需要 \r 才能引发 "line received" 事件。

那里至少有 6 个版本的 netcat,但是 OS X(接近 FreeBSD)上的版本有一个 -c 选项附加 \r\n 到每行的末尾。使用此选项可以解决问题。

$ nc -c localhost 1079 
moshez
Happy and well

注意:LineReceiver 有一个名为 delimiter 的 class 变量,它允许使用任何 EOL 字符。设置 delimiter = '\n' 避免了对 netcat 的 -c 选项的需要。

在 linux,您需要使用 CRLF 作为 EOL

来自 nc 手册页:

-C, --crlf (Use CRLF as EOL) . This option tells Ncat to convert LF. line endings to CRLF. when taking input from standard input.. This is useful for talking to some stringent servers directly from a terminal in one of the many common plain-text protocols that use CRLF for end-of-line.