Paramiko Transport 设置超时
我在使用Paramiko进行端口转发,主要功能运行得很好,但在测试错误情况时遇到了一些问题。我发现当我这样做时,会有很长的超时时间:
port = transport.request_port_forward(my_ip],0)
channel = transport.open_channel('direct-tcpip',(my_ip',22),
('127.0.0.1',port))
问题出在transport.open_channel上:我的设备(my_ip)无法访问,所以paramiko无法连接……我想为这个操作设置一个超时时间,但目前我只知道如何为:
Client.connect()
Channel.settiemout()
设置超时时间。不过Client.connect只适用于连接,而我是在transport.open_channel()之后才得到我的通道……
我在paramiko的文档中找到了这个(Transport):
init(sock)
Create a new SSH session over an existing socket, or socket-like object. This only creates the Transport object; it doesn’t begin the SSH session yet. Use connect or start_client to begin a client session, or start_server to begin a server session.
If the object is not actually a socket, it must have the following methods:
send(str): Writes from 1 to len(str) bytes, and returns an int representing the number of bytes written. Returns 0 or raises EOFError if the stream has been closed.
recv(int): Reads from 1 to int bytes and returns them as a string. Returns 0 or raises EOFError if the stream has been closed.
close(): Closes the socket.
settimeout(n): Sets a (float) timeout on I/O operations.
但我不知道如何调用这个“settimeout(float)”或者如何设置它。我需要创建一个包含这四个方法的对象吗?
提前谢谢你,BR。
1 个回答
0
我找到了修复这个问题的方法……我不知道这是不是最好的办法,但确实有效……我在transport.py里加了这个函数,现在运行得很好:
def open_channel_with_timeout(self, kind,timeout,
dest_addr=None, src_addr=None):
"""
Request a new channel to the server. `Channels <.Channel>` are
socket-like objects used for the actual transfer of data across the
session. You may only request a channel after negotiating encryption
(using `connect` or `start_client`) and authenticating.
:param str kind:
the kind of channel requested (usually ``"session"``,
``"forwarded-tcpip"``, ``"direct-tcpip"``, or ``"x11"``)
:param tuple dest_addr:
the destination address (address + port tuple) of this port
forwarding, if ``kind`` is ``"forwarded-tcpip"`` or
``"direct-tcpip"`` (ignored for other channel types)
:param src_addr: the source address of this port forwarding, if
``kind`` is ``"forwarded-tcpip"``, ``"direct-tcpip"``, or ``"x11"``
:param float timeout: the value of timeout before raising exception
:return: a new `.Channel` on success
:raises SSHException: if the request is rejected or the session ends
prematurely
"""
if not self.active:
raise SSHException('SSH session not active')
self.lock.acquire()
try:
chanid = self._next_channel()
m = Message()
m.add_byte(cMSG_CHANNEL_OPEN)
m.add_string(kind)
m.add_int(chanid)
m.add_int(self.window_size)
m.add_int(self.max_packet_size)
if (kind == 'forwarded-tcpip') or (kind == 'direct-tcpip'):
m.add_string(dest_addr[0])
m.add_int(dest_addr[1])
m.add_string(src_addr[0])
m.add_int(src_addr[1])
elif kind == 'x11':
m.add_string(src_addr[0])
m.add_int(src_addr[1])
chan = Channel(chanid)
self._channels.put(chanid, chan)
self.channel_events[chanid] = event = threading.Event()
self.channels_seen[chanid] = True
chan._set_transport(self)
chan._set_window(self.window_size, self.max_packet_size)
finally:
self.lock.release()
self._send_user_message(m)
egg_timer = 0.0
while True:
event.wait(0.1)
egg_timer += 0.1
if egg_timer > timeout:
e = socket.error('Unable to open channel (Timeout).')
raise e
if not self.active:
e = self.get_exception()
if e is None:
e = SSHException('Unable to open channel.')
raise e
if event.isSet():
break
chan = self._channels.get(chanid)
if chan is not None:
return chan
e = self.get_exception()
if e is None:
e = SSHException('Unable to open channel.')
raise e