使用paramiko端口转发演示时如何避免无限循环?
|
我需要在Python中使用端口转发,才能通过SSH隧道与远程MySQL数据库进行通信。我下载了paramiko软件包,并试用了端口转发演示(forward.py)。它工作得很好,但是我很难将其集成到自己的脚本中(类似于下面的脚本)。当调用主转发函数时,它将进入无限循环,而我的其余代码将不会执行。如何使用forward.py演示并通过无限循环?
我的剧本:
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
没有找到相关结果
已邀请:
2 个回复
凰葱崎济邯
珊畴炮贩号