Python 关闭Twisted conch SSH连接的正确方法是什么?
关闭Twisted conch SSH连接的正确方法是什么?有没有明确的方法可以做到这一点 我看到的所有扭曲海螺示例都关闭SSH通道,然后停止反应堆。反应堆停堆似乎意味着要关闭连接。但是,我正在将wxreactor与wxPython一起使用,我不想停止该反应器,但我想在使用完它后关闭ssh连接 在查看了t.c.s.connection之后,似乎serviceStopped()方法就是最好的选择。它关闭所有打开的通道,并在完成时运行_cleanupGlobalDeferreds(),但随后我开始出现如下异常:Python 关闭Twisted conch SSH连接的正确方法是什么?,python,twisted,twisted.conch,Python,Twisted,Twisted.conch,关闭Twisted conch SSH连接的正确方法是什么?有没有明确的方法可以做到这一点 我看到的所有扭曲海螺示例都关闭SSH通道,然后停止反应堆。反应堆停堆似乎意味着要关闭连接。但是,我正在将wxreactor与wxPython一起使用,我不想停止该反应器,但我想在使用完它后关闭ssh连接 在查看了t.c.s.connection之后,似乎serviceStopped()方法就是最好的选择。它关闭所有打开的通道,并在完成时运行_cleanupGlobalDeferreds(),但随后我开始出
Unhandled Error
Traceback (most recent call last):
File "C:\Users\me\venv\lib\site-packages\twisted\internet\tcp.py", line 203, in doRead
return self._dataReceived(data)
File "C:\Users\me\venv\lib\site-packages\twisted\internet\tcp.py", line 209, in _dataReceived
rval = self.protocol.dataReceived(data)
File "C:\Users\me\venv\lib\site-packages\twisted\conch\ssh\transport.py", line 438, in dataReceived
self.dispatchMessage(messageNum, packet[1:])
File "C:\Users\me\venv\lib\site-packages\twisted\conch\ssh\transport.py", line 460, in dispatchMessage
messageNum, payload)
--- <exception caught here> ---
File "C:\Users\me\venv\lib\site-packages\twisted\python\log.py", line 84, in callWithLogger
return callWithContext({"system": lp}, func, *args, **kw)
File "C:\Users\me\venv\lib\site-packages\twisted\python\log.py", line 69, in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
File "C:\Users\me\venv\lib\site-packages\twisted\python\context.py", line 118, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "C:\Users\me\venv\lib\site-packages\twisted\python\context.py", line 81, in callWithContext
return func(*args,**kw)
File "C:\Users\me\venv\lib\site-packages\twisted\conch\ssh\service.py", line 44, in packetReceived
return f(packet)
File "C:\Users\me\venv\lib\site-packages\twisted\conch\ssh\connection.py", line 228, in ssh_CHANNEL_DATA
channel = self.channels[localChannel]
exceptions.KeyError: 0
调用此方法时,self.factory.d似乎始终为None,因此它返回时不调用t.c.s.t.SSHClientTransport.sendDisconnect()。我认为它最初是t.c.c.d.connect中的一个延迟集,但在某个点上它被设置为“无”
我怀疑SSHClientTransport.loseConnection()是关闭SSH连接的正确方法,但是为什么当twisted希望self.factory.d是其他连接时,self.factory.d设置为None呢
如果loseConnection()不是关闭SSH连接的正确方法,有人能给我指出正确的方向吗?听起来你在使用
twisted.conch.client.direct.SSHClientFactory
和twisted.conch.client.direct.SSHClientTransport
。这些类最直接地用于实现conch
命令行工具。这意味着它们对于构建SSH客户机非常有用,因为这正是conch
的含义
然而,它们也没有人们想象的那么有用,因为除了实现conch
命令行工具之外,它们不太注意做任何“其他”事情
更普遍适用的SSH客户端传输类是
twisted.conch.SSH.transport.SSHClientTransport
。这个类没有任何额外的逻辑来实现conch
命令行工具的某些特定行为。它只有SSH客户端逻辑。例如,它没有一个无法解释的self.factory.d
内部检查sendDisconnect
-它的sendDisconnect
实现只是发送一个断开数据包,然后关闭连接。我遇到了同样的问题。我确信这是一个bug,sendDisconnect()
不调用父实现。在SSHClientTransport
上调用loseConnection()
不会为我关闭TCP连接,我可以使用lsof-p PID
看到这一点。为了解决这个问题,我使用自己的connect()
方法注入自己的SSHClientTransport
实现。以下代码修复了该问题:
class SSHClientTransport(direct.SSHClientTransport):
'''
Orignal sendDisconnect() is bugged.
'''
def sendDisconnect(self, code, reason):
d, self.factory.d = self.factory.d, None
# call the sendDisconnect() on the base SSHTransport,
# not the imediate parent class
transport.SSHClientTransport.sendDisconnect(self, code, reason)
if d:
d.errback(error.ConchError(reason, code))
def sendDisconnect(self, code, reason):
if self.factory.d is None:
return
d, self.factory.d = self.factory.d, None
transport.SSHClientTransport.sendDisconnect(self, code, reason)
d.errback(error.ConchError(reason, code))
class SSHClientTransport(direct.SSHClientTransport):
'''
Orignal sendDisconnect() is bugged.
'''
def sendDisconnect(self, code, reason):
d, self.factory.d = self.factory.d, None
# call the sendDisconnect() on the base SSHTransport,
# not the imediate parent class
transport.SSHClientTransport.sendDisconnect(self, code, reason)
if d:
d.errback(error.ConchError(reason, code))