[Twisted-Python] Telnet negotiation with Twisted
Patrick Mylund Nielsen
twisted at patrickmylund.com
Sat Dec 3 09:22:19 EST 2011
Hi Lee,
Here is a complete example that works with Twisted 11.0. LINEMODE
itself is enabled at connect, but it has different modes that
determine what is sent when by the client. (See section 2.2 of
http://www.faqs.org/rfcs/rfc1184.html)
#####
#!/usr/bin/env python
from twisted.internet.protocol import Factory
from twisted.conch.telnet import TelnetProtocol,
StatefulTelnetProtocol, TelnetTransport
from twisted.conch.telnet import DO, DONT, WILL, WONT
LINEMODE = chr(34)
LINEMODE_EDIT = chr(1) + chr(1)
LINEMODE_TRAPSIG = chr(1) + chr(2)
LINEMODE_MODEACK = chr(1) + chr(4)
LINEMODE_SOFTTAB = chr(1) + chr(8)
LINEMODE_LITECHO = chr(1) + chr(16)
class LineModeProtocol(TelnetProtocol):
def connectionMade(self):
print("Connection made!")
def connectionLost(self, reason):
print("Connection lost!")
def dataReceived(self, data):
if self.transport.lines:
line = data.rstrip()
print("data received (normal): " + line)
if line == "gounbuffered":
self.transport.requestNegotiation(LINEMODE,
LINEMODE_TRAPSIG) # Only trap signals locally
self.transport.lines = False
else:
# manually buffer data here
print("data received (linemode): " + data)
if data == "n":
self.transport.requestNegotiation(LINEMODE,
LINEMODE_EDIT) # Change to edit mode
self.transport.lines = True
class LineModeTransport(TelnetTransport):
def connectionMade(self):
self.lines = True
self.do(LINEMODE) # Ask client to begin sub-negotation of linemode
TelnetTransport.connectionMade(self)
def commandReceived(self, command, argument):
if argument == LINEMODE:
if command == WILL: # Client said OK to our DO; let's... do it
self.requestNegotiation(LINEMODE, LINEMODE_EDIT) # The
normal (buffered) mode
else:
TelnetTransport.commandReceived(self, command, argument)
class LineModeFactory(Factory):
def buildProtocol(self, addr):
return LineModeTransport(LineModeProtocol)
if __name__ == '__main__':
from twisted.internet import reactor
port = 2222
factory = LineModeFactory()
reactor.listenTCP(port, factory)
reactor.run()
#####
There is probably an easier way to check the state of LINEMODE, e.g.
with getOptionState, but it works.
Example:
Client:
# telnet localhost 2222
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
How are you?
gounbuffered
testnback again
Server:
# ./linemode.py
Connection made!
data received (normal): How are you?
data received (normal): gounbuffered
data received (linemode): t
data received (linemode): e
data received (linemode): s
data received (linemode): t
data received (linemode): n
data received (normal): back again
Best,
Patrick
On Sat, Dec 3, 2011 at 14:59, <exarkun at twistedmatrix.com> wrote:
> On 03:53 am, lmorsino at gmail.com wrote:
>>Jean-Paul,
>>
>>Thanks for your response. I still can't get self.will(LINEMODE) to work
>>but
>>I did get self.telnet_WILL(LINEMODE) to run without throwing an Error.
>>Can
>>you elaborate on what needs to happen in the enableRemote? My
>>impression
>>was that once I send the negotiation WILL command from server to the
>>client, the client will respond with either a DO or a DONT. What
>>further
>>logic is necessary?
>
> I can't say what further logic is necessary, because I don't know what
> logic you have now. The description of your code you gave above is a
> good introduction to an actual code listing (<http://sscce.org/>), but
> it's not sufficient on its own.
>
> Jean-Paul
>
> _______________________________________________
> Twisted-Python mailing list
> Twisted-Python at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
More information about the Twisted-Python
mailing list