python的paramiko模块用sftp下载大文件时失败

荒村归来 2017-12-19 04:39:13
【软件版本】
python 版本3.4
paramiko 版本2.4.0
客户端环境:windows 7 x64
服务器环境:linux

【问题描述:】
使用paramiko模块连接sftp服务器,密码登录,下载文件时,总是在下载到28770304byte左右卡住。
下载小文件时,没有问题,下载大文件时,就会出现此现象
网上搜索到类似问题,但没有解决方法
参考:https://segmentfault.com/q/1010000006090487

【源代码】

import paramiko
import os
import os.path

username='test'
password='test'
host='192.168.1.1'
port=22
t=paramiko.Transport((host,port))
t.connect(username=username,password=password)
sftp=paramiko.SFTPClient.from_transport(t)

rpath='/test.rar'
try:
sftp.get(rpath,r'D:\TEMP\1.rar',print) #下载文件
except Exception as e:
print(e)
t.close()


PS:好久没用CSDN了,没有分,实在不好意思,仅在此感谢大家的帮助。
...全文
1751 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
Xzchen555 2019-09-11
  • 打赏
  • 举报
回复
client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.load_system_host_keys() client.connect(hostname, username=username, password=password, port=port) tr = client.get_transport() tr.default_max_packet_size = 100000000 tr.default_window_size = 100000000 sftp = client.open_sftp() sftp.get(remote_file, local_filepath) client.close() 测了下比上面修改函数性能好。
qq_30682059 2018-01-02
  • 打赏
  • 举报
回复
这种改法确实可以下包了,但是速度很慢,有优化的写法么
oyljerry 2017-12-20
  • 打赏
  • 举报
回复
卡住有没有exception,是不是网络超时了
荒村归来 2017-12-20
  • 打赏
  • 举报
回复 1
引用 3 楼 oyljerry 的回复:
[quote=引用 2 楼 huangcunguilai 的回复:] [quote=引用 1 楼 oyljerry 的回复:] 卡住有没有exception,是不是网络超时了
网络没有超时,也没有抛出异常,我特地修改了Python34\Lib\site-packages\paramiko\sftp_file.py文件中的函数def _data_in_prefetch_buffers(self, offset):,把其中的数据打印出来看了,大致现象就是出现丢包,中间出现几次空白后,包就调到后面的数据了,而且还是乱序的。[/quote] https://stackoverflow.com/questions/12486623/paramiko-fails-to-download-large-files-1gb[/quote] 的确是最后一位回答者说的原因,我在多线程中添加sleep就可以完整下载,其他几个答案的局限性比较强。不过我这边添加sleep对性能影响较大,暂时没有去重写异步控制。 非常感谢您的帮助。 【我暂时的解决方法】 修改Python34\Lib\site-packages\paramiko\sftp_file.py的_prefetch_thread函数,添加了线程数控制

threadnum = threadnum + 1
            if threadnum == 100:
                #print(threadnum)
                threadnum=0
                time.sleep(1)
修改完代码如下:
    def _prefetch_thread(self, chunks):
        # do these read requests in a temporary thread because there may be
        # a lot of them, so it may block.
        threadnum=0
        for offset, length in chunks:
            threadnum = threadnum + 1
            if threadnum == 100:
                #print(threadnum)
                threadnum=0
                time.sleep(1)
            num = self.sftp._async_request(
                self,
                CMD_READ,
                self.handle,
                long(offset),
                int(length))
            with self._prefetch_lock:
                self._prefetch_extents[num] = (offset, length)
oyljerry 2017-12-20
  • 打赏
  • 举报
回复
引用 2 楼 huangcunguilai 的回复:
[quote=引用 1 楼 oyljerry 的回复:] 卡住有没有exception,是不是网络超时了
网络没有超时,也没有抛出异常,我特地修改了Python34\Lib\site-packages\paramiko\sftp_file.py文件中的函数def _data_in_prefetch_buffers(self, offset):,把其中的数据打印出来看了,大致现象就是出现丢包,中间出现几次空白后,包就调到后面的数据了,而且还是乱序的。[/quote] https://stackoverflow.com/questions/12486623/paramiko-fails-to-download-large-files-1gb
荒村归来 2017-12-20
  • 打赏
  • 举报
回复
引用 1 楼 oyljerry 的回复:
卡住有没有exception,是不是网络超时了
网络没有超时,也没有抛出异常,我特地修改了Python34\Lib\site-packages\paramiko\sftp_file.py文件中的函数def _data_in_prefetch_buffers(self, offset):,把其中的数据打印出来看了,大致现象就是出现丢包,中间出现几次空白后,包就调到后面的数据了,而且还是乱序的。

37,743

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • WuKongSecurity@BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧