我正在使用 Paramiko 的 SFTP 客户端将文件从远程服务器下载到客户端(即获取操作)
要传输的文件有点大~1GB。
所以我希望如果时间超过10秒,get操作就会超时。
但是设置连接的超时值不起作用,它似乎只是创建 SSH 连接的超时,而不是整个 ssh 连接的超时。
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=username, password=password, timeout=10.0)
sftp = ssh.open_sftp()
start_time = time.time()
sftp.get(local_path,remote_path)
elapsed_time = time.time()-start_time
print elapsed_time
sftp.close()
我也尝试设置通道的超时值,但它也不起作用
sftp.get_channel.settimeout(10.0)
但这个超时又只是针对读/写操作
有一个类似的问题paramiko 中的超时(python) https://stackoverflow.com/questions/9758432/timeout-in-paramiko-python/40221590#40221590但它只对创建 SSH 连接超时有答案
更新1:根据@Martin的评论,我实现了一个回调函数,用于检查sftp的get操作的时间限制:
import paramiko
import time
Class TimeLimitExceeded(Exception):
pass
timelimit = 10
start_time = time.time()
def _timer():
elapsed_time = time.time()-start_time
if elapsed_time > timelimit:
raise TimeLimitExceeded
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=username, password=password, timeout=10.0)
sftp = ssh.open_sftp()
try:
sftp.get(local_path,remote_path,_timer)
except TimeLimitExceeded:
print "The operation took too much time to complete"
sftp.close()
但是排除异常的时间很多,代码在某个地方阻塞了。
我深入研究了 Paramiko 源代码,发现其背后的罪魁祸首是_close(self,async=False)
的方法sftp_file.py
有什么帮助解决这个问题吗?
更新 2:如果超过时间限制,则尝试关闭通道本身。
然后异常被刷新到控制台prefetch
由单独的守护线程实现
File "/scratch/divjaisw/python2.7/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/scratch/divjaisw/python2.7/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/scratch/divjaisw/python_virtual/lib/python2.7/site-packages/paramiko/sftp_file.py", line 488, in _prefetch_thread
num = self.sftp._async_request(self, CMD_READ, self.handle, long(offset), int(length))
File "/scratch/divjaisw/python_virtual/lib/python2.7/site-packages/paramiko/sftp_client.py", line 754, in _async_request
self._send_packet(t, msg)
File "/scratch/divjaisw/python_virtual/lib/python2.7/site-packages/paramiko/sftp.py", line 170, in _send_packet
self._write_all(out)
File "/scratch/divjaisw/python_virtual/lib/python2.7/site-packages/paramiko/sftp.py", line 133, in _write_all
n = self.sock.send(out)
File "/scratch/divjaisw/python_virtual/lib/python2.7/site-packages/paramiko/channel.py", line 715, in send
return self._send(s, m)
File "/scratch/divjaisw/python_virtual/lib/python2.7/site-packages/paramiko/channel.py", line 1081, in _send
raise socket.error('Socket is closed')
error: Socket is closed