Python实现FTP文件传输的实例


Posted in Python onJuly 07, 2019

FTP一般流程

FTP对应PASV和PORT两种访问方式,分别为被动和主动,是针对FTP服务器端进行区分的,正常传输过程中21号端口用于指令传输,数据传输端口使用其他端口。

PASV:由客户端发起数据传输请求,服务器端返回并携带数据端口,并且服务器端开始监听此端口等待数据,为被动模式;

PORT:客户端监听端口并向服务器端发起请求,服务器端主动连接此端口进行数据传输,为主动模式。

Python实现FTP文件传输的实例

其中TYPE分两种模式,I对应二进制模式、A对应ASCII模式;

PASV为客户端发送请求,之后227为服务器端返回操作码表示成功,并且后面带有服务器端监听的端口:143x256(左移8位)+48

之后通过STOR命令进行数据下载,下载完成后返回226表示数据传输完成。

2. Python代码实现:

中文路径问题:由于FTP支持ASCII编码,Python ftplib中编码方式使用latin-1,而window默认编码方式为gbk,所以使用Python处理时需先将中文路径编码为gbk之后译码为latin-1字符;

上传下载使用storline和retrline,对应二进制使用storbinary和retrbinary。对于stor类函数后面的参数fp表示接收一个文件对象,支持read方法,一般为打开需要上传的源文件,而retr类函数后面的参数表示对于返回数据的处理方法。

从一个FTP服务器到另一个FTP服务器的数据传输:

利用本地电脑作为数据缓存,但并不将数据保存到硬盘,只在内存中存储进行数据传输;其中一端作为下载一端为数据上传。

首先登陆两个FTP服务器,transfercmd函数用于发送命令并返回已建立好连接的本地Socket,此时分别在两个本地Socket进行数据的收发即可。

在测试中发现,在发送完一个文件之后只有及时的关闭socket,21端口才会返回226,数据完成指示,这样才可以循环下一个文件,在完成之后要退出FTP。

#coding=utf-8

import ftplib,os.path,os
import socket

f1=ftplib.FTP('172.16.2.76')
f2=ftplib.FTP('172.16.25.153')


class myFTP:
    path='file/download/bbb/'
    # ftplib中编码使用latin-1
    title='版本'.encode(encoding='gbk').decode(encoding='latin-1')
    path1=path+title  
    localDir='E:\\ver\\fp\\'
    
    path2='abc/edf/'
    

    def __init__(self):
           
      try:
        f1.login('username','password')
      except ftplib.error_perm:
        print('f1 cannot loggin!')
        return

      try:
        f2.login()
      except ftplib.error_perm:
        print('f2 cannot loggin!')
        return
        
    def ftpD(self):
             
      filelist=[]
      fileLIST=[]
      filels=f1.retrlines('LIST %s'%(self.path1),callback=filelist.append)
      f1.cwd(self.path1)
      for file in filelist:
        fileAttr=file.split(' ')
        fileName=fileAttr[-1]
        fileType=fileAttr[0][0]
        if fileType=='-':
          fileLIST.append(fileName)
    
      for file in fileLIST:
        path=self.localDir+file
        f1.retrbinary('RETR %s'%(file),open(path,'wb').write)
        print('%s download.....'%(file))    
      f1.quit()
    
    def ftpU(self,fun=1):
    
      os.chdir(self.localDir)
      fileList=os.listdir()
      
      # upload file
      if fun==1:
          for file in fileList:
            path=self.path2
            f2.storbinary('STOR %s'%(path+file),open(file,'rb'))
            print('%s uploading......'%(file))
      
      #delete file
      if fun==0:
          try:
              for file in fileList:
                path=self.path2
                f2.delete(path+file)
                print('%s delete......'%(file))
          except ftplib.error_perm:
              print('no file to delete!!')
              return
      
      f2.quit()
    
    def test(self):
      
      f1.cwd(self.path1)
      f2.cwd(self.path2)
      fileList=f1.nlst()
      print(fileList)
      
      for file in fileList:
        print('transfer %s......'%(file))
        f1.voidcmd('TYPE I')
        f2.voidcmd('TYPE I')
        sock1=f1.transfercmd('RETR %s'%(file))
        sock2=f2.transfercmd('STOR %s'%(file))
    
        while 1:
      
            data=sock1.recv(1024)
            sock2.sendall(data)
            
            if len(data)==0:
              break
        # 数据发送完成后需关闭socket,服务器21端口才会有返回    
        sock1.close()
        sock2.close()
            
                          
        res1=f1.getresp()
        #print('f1 >> %s'%(res1))
        res2=f2.getresp()
        #print('f2 >> %s'%(res2))    
                   
      f1.quit()
      f2.quit()

    
if __name__=='__main__':
  ftptest=myFTP() 
  ftptest.ftpU(0)
  #ftptest.test()
  #ftptest.ftpD()
Python 相关文章推荐
python使用mailbox打印电子邮件的方法
Apr 30 Python
python实现的DES加密算法和3DES加密算法实例
Jun 03 Python
python使用MySQLdb访问mysql数据库的方法
Aug 03 Python
python图书管理系统
Apr 05 Python
Python查找两个有序列表中位数的方法【基于归并算法】
Apr 20 Python
便捷提取python导入包的属性方法
Oct 15 Python
python3爬虫学习之数据存储txt的案例详解
Apr 24 Python
Python+Redis实现布隆过滤器
Dec 08 Python
关于Python Tkinter Button控件command传参问题的解决方式
Mar 04 Python
Python3标准库glob文件名模式匹配的问题
Mar 13 Python
解决python多线程报错:AttributeError: Can't pickle local object问题
Apr 08 Python
Python使用pycharm导入pymysql教程
Sep 16 Python
Python爬虫动态ip代理防止被封的方法
Jul 07 #Python
Python异常处理例题整理
Jul 07 #Python
解决pycharm下os.system执行命令返回有中文乱码的问题
Jul 07 #Python
在python中实现调用可执行文件.exe的3种方法
Jul 07 #Python
Python求两点之间的直线距离(2种实现方法)
Jul 07 #Python
对Python中画图时候的线类型详解
Jul 07 #Python
Python 3 实现定义跨模块的全局变量和使用教程
Jul 07 #Python
You might like
一个改进的UBB类
2006/10/09 PHP
PHP Error与Logging函数的深入理解
2013/06/03 PHP
php 创建以UNIX时间戳命名的文件夹(示例代码)
2014/03/08 PHP
PHP使用Mysql事务实例解析
2014/09/08 PHP
再Docker中架设完整的WordPress站点全攻略
2015/07/29 PHP
thinkphp多层MVC用法分析
2015/12/30 PHP
PDO::_construct讲解
2019/01/27 PHP
php中array_fill函数的实例用法
2021/03/02 PHP
CSS中一些@规则的用法小结
2021/03/09 HTML / CSS
基于JQuery的访问WebService的代码(可访问Java[Xfire])
2010/11/19 Javascript
jquery 插件学习(一)
2012/08/06 Javascript
关于JavaScript的面向对象和继承有利新手学习
2013/01/11 Javascript
Javascript实现动态菜单添加的实例代码
2013/07/05 Javascript
javascript 获取图片尺寸及放大图片
2013/09/04 Javascript
js中array的sort()方法使用介绍
2014/02/20 Javascript
jquery日历控件实现方法分享
2014/03/07 Javascript
JQuery日历插件My97DatePicker日期范围限制
2016/01/20 Javascript
Web Uploader文件上传插件使用详解
2016/05/10 Javascript
Javascript类型系统之String字符串类型详解
2016/06/21 Javascript
js完整倒计时代码分享
2016/09/18 Javascript
jQuery监听文件上传实现进度条效果的方法
2016/10/16 Javascript
jquery uploadify隐藏上传进度的实现方法
2017/02/06 Javascript
JS设置随机出现2个数字的实例代码
2017/07/19 Javascript
Angularjs中的验证input输入框只能输入数字和小数点的写法(推荐)
2017/08/16 Javascript
JS中跳出循环的示例代码
2017/09/14 Javascript
Node解决简单重复问题系列之Excel内容的获取
2018/01/02 Javascript
Javascript中的奇葩知识,你知道吗?
2021/01/25 Javascript
python使用xauth方式登录饭否网然后发消息
2014/04/11 Python
python打包压缩、读取指定目录下的指定类型文件
2018/04/12 Python
pycharm远程linux开发和调试代码的方法
2018/07/17 Python
Python玩转PDF的各种骚操作
2019/05/06 Python
python添加菜单图文讲解
2019/06/04 Python
python PyAutoGUI 模拟鼠标键盘操作和截屏功能
2019/08/04 Python
招商业务员岗位职责
2013/12/16 职场文书
债务授权委托书范本
2014/10/17 职场文书
公司股份转让协议书范本
2015/01/28 职场文书