My goal is to create telnet clients as endpoints per the TCP4ClientEndpoint implementation.
Here’s what Im doing:
class TelnetClient( TelnetProtocol ):
...
factory = Factory()
factory.protocol = TelnetClient
point = TCP4ClientEndpoint( reactor, x.x.x.x, 23 )
defer = point.connect( factory )
defer.addCallback( todo )
reactor.run
The TelnetClient class handles authentication, logging in, firing commands, etc.
when I use this approach, I can read some output off of dataReceived, but it’s giberish.
The telnet client functions as expected when it is constructed by a Factory and then reactor.connectTCP(...) is called with the Factory.
What is it that Im doing wrong here?
Thanks!
EDIT 1 connecting TelnetClient to factory.protocol via TelnetProtocol
class TelnetClient( TelnetProtocol ):
...
factory = Factory()
factory.protocol = TelnetTransport( TelnetClient )
point = TCP4ClientEndpoint( reactor, x.x.x.x, 23 )
defer = point.connect( factory )
defer.addCallback( todo )
reactor.run
EDIT 2 solved. The final piece was ClientFactory.
class TelnetClient( TelnetProtocol ):
...
factory = ClientFactory()
factory.protocol = TelnetTransport( TelnetClient )
point = TCP4ClientEndpoint( reactor, x.x.x.x, 23 )
defer = point.connect( factory )
Solving this problem was two fold.
-
Since we want a telnet client, we need to ensure that the protocol is an instance of
TelnetProtocol. -
The factory must be of
ClientFactory. If we look at the source oftwisted.internet.endoints, we see that the factory we pass in to the endpoints is wrapped in_WrappingFactory, which is descended fromClientFactory. If this factory we pass in does not have the same attributes asClientFactory, then the_wrappedFactorywill cause AttributeErrors when it attempts to call methods of ClientFactory
You’re correct that
connectTCPandendpoint.connectare functionally the same (for the most part).Assuming that
TelnetProtocolistwisted.conch.telnet.TelnetProtocol, the problem here is thatTelnetProtocolis not really supposed to connect directly to a TCP transport, it’s supposed to connect to atwisted.conch.telnet.TelnetTransport. That “gibberish” indataReceivedthat you’re seeing are the actual telnet protocol bytes, which are supposed to be parsed by atwisted.conch.telnet.TelnetTransport(which is itself anIProtocol) in order to call methods likeenableLocalandenableRemoteon theTelnetTransport.I would guess that in your
connectTCP-based example, you are probably instantiating aTelnetTransportand setting its.protocolattribute to point at aTelnetProtocol.Basically, make sure that the
Factoryobject that you’re passing in has exactly the sameprotocolattribute as theClientFactoryyou’re using in yourconnectTCPexample.In the future, also, please include complete, runnable code examples so that we can run them and see what happens rather than guessing :-).