Search code examples
pythontwistedtelnetnetcat

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


I'm following a Twisted tutorialand tried the following code from that article:

# 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()

I tried nc localhost 1079 and it just hangs: no replies. But then telnet localhost 1079 works just fine. Why?


Solution

  • Using wireshark, I figured out the following: telnet was sending 0x0d and then 0x0a (ie, "\r\n") for the line terminator. However netcat was sending only 0x0a. This was on Ubuntu (and also on OS X).

    Apparently the LineReceiver protocol in Twisted requires the \r in order to raise the "line received" event.

    There are at least 6 versions of netcat out there, but the one on OS X (which is close to FreeBSD) has a -c option that appends \r\n to the end of each line. Using this option fixes the problem.

    $ nc -c localhost 1079 
    moshez
    Happy and well
    

    Note: LineReceiver has a class variable called delimiter that allows any EOL character to be used. Setting delimiter = '\n' obviates the need for the -c option to netcat.