我的目标是根据TCP4ClientEndpoint实现将telnet客户端创建为端点。

我在做什么:

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


TelnetClient类处理身份验证,登录,触发命令等。

当我使用这种方法时,我可以从dataReceived读取一些输出,但是它有点呆板。

telnet客户端由Factory构造,然后使用reactor.connectTCP(...)调用Factory时,将按预期的功能运行。

我在这里做错了什么?

谢谢!

编辑1通过TelnetClientfactory.protocol连接到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


编辑2解决。最后一块是ClientFactory。

class TelnetClient( TelnetProtocol ):
    ...

factory = ClientFactory()
factory.protocol = TelnetTransport( TelnetClient )
point = TCP4ClientEndpoint( reactor, x.x.x.x, 23 )
defer = point.connect( factory )


解决这个问题有两个方面。


由于我们需要telnet客户端,因此需要确保该协议是TelnetProtocol的实例。
工厂必须是ClientFactory。如果查看twisted.internet.endoints的来源,则会看到传递到端点的工厂包装在_WrappingFactory中,该工厂是ClientFactory的后代。如果我们传入的工厂的属性与ClientFactory不同,则_wrappedFactory尝试调用ClientFactory的方法时将导致AttributeErrors

最佳答案

您正确地认为connectTCPendpoint.connect在功能上是相同的(大部分情况下)。

假设TelnetProtocoltwisted.conch.telnet.TelnetProtocol,那么这里的问题是TelnetProtocol并不是真正应该直接连接到TCP传输,而应该连接到twisted.conch.telnet.TelnetTransport。您看到的dataReceived中的“乱码”是实际的telnet协议字节,应该由twisted.conch.telnet.TelnetTransport(其本身是IProtocol)进行解析,以便调用诸如enableLocalenableRemote上的TelnetTransport

我猜想在您基于connectTCP的示例中,您可能正在实例化TelnetTransport并将其.protocol属性设置为指向TelnetProtocol

基本上,确保要传递的Factory对象具有与protocol示例中使用的ClientFactory完全相同的connectTCP属性。

将来,还请提供完整的可运行代码示例,以便我们可以运行它们并查看会发生什么,而不是猜测:-)。

08-28 04:30