Python 使用paramiko端口转发演示时,如何避免无限循环?
我需要在Python中使用端口转发通过SSH隧道与远程MySQL DB通信。我下载了paramiko包并试用了端口转发演示(forward.py)。它工作得非常好,但是我在将它集成到我自己的脚本中时遇到了困难(类似于下面的脚本)。当调用主转发函数时,它会进入一个无限循环,我的代码的其余部分不会执行。如何使用forward.py演示并通过无限循环 我的剧本:Python 使用paramiko端口转发演示时,如何避免无限循环?,python,multithreading,infinite-loop,paramiko,portforwarding,Python,Multithreading,Infinite Loop,Paramiko,Portforwarding,我需要在Python中使用端口转发通过SSH隧道与远程MySQL DB通信。我下载了paramiko包并试用了端口转发演示(forward.py)。它工作得非常好,但是我在将它集成到我自己的脚本中时遇到了困难(类似于下面的脚本)。当调用主转发函数时,它会进入一个无限循环,我的代码的其余部分不会执行。如何使用forward.py演示并通过无限循环 我的剧本: import paramiko import forward import MySQLdb import cfg import sys c
import paramiko
import forward
import MySQLdb
import cfg
import sys
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.WarningPolicy())
try:
client.connect(cfg.remhost, cfg.remport, username=cfg.user, password=cfg.password)
except Exception, e:
print '*** Failed to connect to %s:%d: %r' % (cfg.remhost, cfg.remport, e)
sys.exit(1)
try:
forward.forward_tunnel(3306, cfg.remhost, 3306, client.get_transport())
except KeyboardInterrupt:
print 'C-c: Port forwarding stopped.'
sys.exit(0)
try:
db = MySQLdb.connect('127.0.0.1', cfg.dbuser, cfg.dbpass, cfg.dbname)
except Exception, e:
print 'Failed to connect to database'
sys.exit(1)
try:
cursor = self.db.cursor(MySQLdb.cursors.DictCursor)
sql = 'SELECT * FROM ' + cfg.dbtable
cursor.execute(sql)
results = cursor.fetchall()
print str(len(results))
except Exception, e:
print 'Failed to query database'
sys.exit(1)
下面是forward.py演示代码的主要部分:
class ForwardServer (SocketServer.ThreadingTCPServer):
daemon_threads = True
allow_reuse_address = True
class Handler (SocketServer.BaseRequestHandler):
def handle(self):
try:
chan = self.ssh_transport.open_channel('direct-tcpip',
(self.chain_host, self.chain_port),
self.request.getpeername())
except Exception, e:
verbose('Incoming request to %s:%d failed: %s' % (self.chain_host,
self.chain_port,
repr(e)))
return
if chan is None:
verbose('Incoming request to %s:%d was rejected by the SSH server.' %
(self.chain_host, self.chain_port))
return
verbose('Connected! Tunnel open %r -> %r -> %r' % (self.request.getpeername(),
chan.getpeername(), (self.chain_host, self.chain_port)))
while True:
r, w, x = select.select([self.request, chan], [], [])
if self.request in r:
data = self.request.recv(1024)
if len(data) == 0:
break
chan.send(data)
if chan in r:
data = chan.recv(1024)
if len(data) == 0:
break
self.request.send(data)
chan.close()
self.request.close()
verbose('Tunnel closed from %r' % (self.request.getpeername(),))
def forward_tunnel(local_port, remote_host, remote_port, transport):
# this is a little convoluted, but lets me configure things for the Handler
# object. (SocketServer doesn't give Handlers any way to access the outer
# server normally.)
class SubHander (Handler):
chain_host = remote_host
chain_port = remote_port
ssh_transport = transport
ForwardServer(('', local_port), SubHander).serve_forever()
def verbose(s):
if g_verbose:
print s
我认为您需要处理程序转发代码在自己的线程中运行,并使用队列与之通信 或者从你自己的循环中取出相关的电话和东西。嗯,我不确定这到底是怎么回事
您希望mysql调用在您的程序中使用它,还是从其他程序转发?我是Pyhon模块Python X2Go的上游作者,该模块大量使用Paramiko进行SSH会话管理 请查看代码中的forward.py文件: Python X2Go的代码大量使用Python gevent进行服务器-客户端通信、端口转发等 问候,
迈克好吧,既然似乎没有人想回答这个问题,我的新问题是:我原来的问题让其他人都不高兴了,那怎么办?我应该改变什么,这样人们才会真正做出反应?我需要重新措辞还是添加更多信息?谢谢你的回复。看起来我需要学习如何在Python中运行线程。我不需要转发脚本成为数据库脚本的一部分,它们也不需要相互通信。DB呼叫被发送到127.0.0.1:3306,转发脚本已将其转发到远程服务器。我只是很惊讶,我找不到一个这样的例子已经张贴在某处。我尝试这样做,但无法让它工作。这是因为我的web主机拒绝端口转发。我尝试编写自己的应用程序,在创建SSH连接后在远程主机上运行,但无法使其工作。我确实收到了一些文本,但它无法与mysql服务器正确握手。很抱歉,当我意识到我的web主机是共享主机并阻止端口转发时,我不再处理Paramiko的东西了。欢迎使用堆栈溢出。请阅读我们的:在文章中包含有用的内容,并提供链接供参考。在这里,您能提供一些演示端口转发的代码(10-20行就好了)吗?