python编写ftp客户端_用python实现FTP客户端

暑假做的唯一一个有意义的项目吧,其实原理很简单。主要是其中学了不少Ubuntu的东西。今天正好没事,整理一下,以便后面查阅。

首先推荐一个好用的FTP管理程序--IIS7服务器管理工具:

“IIS7服务器管理工具是一款windows全系、Linux系统下链接并操控VPS、VNC、FTP等远程服务器、云服务器。

界面简单明了,操作易上手,功能强大,支持批量导入服务器,并批量打开,多窗口化管理,除此之外,加载本地硬盘、硬盘映射、加载服务器的声音,远程声卡读取等,完全实现各类场景使用,对于FTP链接界面,朋友FTP定时上传,定时下载(也可以说定时上传下载 定时备份),对于经常使用FTP的小伙伴来说,非常适用。

工具支持自动更新,压缩包只有7.62M,方便简洁,一步到位。“

使用说明:

一、 程序说明。

程序功能:这个程序主要由三个功能。1.浏览ftp服务器目录。2.随机下载一个文件。3.随机下载多个文件。

1.       浏览ftp服务器目录。

这个功能主要是在登入进ftp服务器后,生成一个随机数,根据随机数,进行判断往哪个目录下索引。如果是根目录,只会向下索引。如果是底层目录,只会向上索引。

2.       随机下载一个文件。

这个功能主要是在登入进ftp服务器后,生成一个随机数,根据随机数,随机下载一个文件。需要注意的是,生成随机数之前,要进行判断。如果没有要下载的文件,就要切换目录,进行下载。

3.       随机多个文件下载

这个功能主要是在登入ftp服务器后,随机下载多个文件。实现原理为,首先进入一个目录下,判断是否有文件下载,如果有文件下载,则下载多个文件,如果没有,则改变目录。完成后改变目录。

所需参数:“ip,port,username,passwd,usermodel”。传入参数由一个字符串组成。用逗号进行分割。

所需环境:需要搭建好ftp服务器。以及有python环境的系统上运行。

注意事项:

1.       下载路径默认为”/home/”。如果程序出错提示为“不能写入”,需要对文件权限进行提升。

2.       在实现用户模式时,程序已经默认多次执行。即每次运行程序时,就会随机多次(至少一次,最多5次)执行,用来模拟用户行为。

3.       ftp服务器搭建详见ftp服务器搭建教程。

1 #!/usr/bin/env Python3

2 #-*- encoding:utf-8 -*-

3 from ftplib importFTP4 from random importrandint5 importtime6 importsys7

8

9

10

11 defftpconnect(ip, port, username, passwd):12 ftp =FTP()13 #ftp.set_debuglevel(2) # 打开调试级别2,显示详细信息

14 ftp.connect(ip, port) #连接的ftp服务器ip和port

15 ftp.login(username, passwd) #连接的用户名和密码

16 print(ftp.getwelcome()) #打印出欢迎信息。

17 returnftp18

19 defshowdownloadfile(ftp):20 #print("当前目录下的文件:文件夹名字:"+ftp.pwd())

21 mu_dir =gettable(ftp)22 #print("当前文件夹: "+ftp.pwd()+" 可供下载的文件:")

23 behind_name =[]24 for name inmu_dir:25 if mu_dir[name] == "文件":26 behind_name.append(name)27 #print(name)

28 returnbehind_name29

30 defshowfolderfile(ftp):31 #print("当前目录下的文件:文件夹名字:"+ftp.pwd())

32 mu_dir =gettable(ftp)33 #print("当前文件夹: "+ftp.pwd()+" 可供索引的文件夹:")

34 folder_name =[]35 for name inmu_dir:36 if mu_dir[name] == "文件夹":37 folder_name.append(name)38 #print(name)

39 returnfolder_name40

41 defrandomdownload(ftp, localpath, str):42 #当前目录下可供下载的文件名字

43 behind_name =showdownloadfile(ftp)44 #print("当前文件夹: "+ftp.pwd()+" 可供下载的文件:")

45 #print(behind_name)

46 #随机数

47 while len(behind_name) == 0: #说明没有可以下载的文件

48 #切换文件夹

49 changetable(ftp,str)50 behind_name =showdownloadfile(ftp)51 file_random = randint(0, len(behind_name)-1)52 filename =behind_name[file_random]53 print("当前目录为:"+ftp.pwd())54 print("下载文件为"+filename)55 #设置下载数据

56 bufsize = 1024 #设置缓冲区大小

57 new_path = localpath+filename #设置下载路径

58

59 fp = open(new_path, 'wb')60 ftp.retrbinary('RETR' + filename, fp.write, bufsize) #下载FTP文件。FTP命令 RETR filename

61 fp.close()62 print(filename+'下载成功')63

64

65 def downloadfiles(ftp, localpath, str): #根目录不能继续向下,没有目录不能索引(这个可以自动实现)。

66 #在当前目录下随机下载几个文件

67 behind_name =showdownloadfile(ftp)68 #folder_name = showfolderfile(ftp)

69 while len(behind_name) == 0: #说明没有可以下载的文件

70 #切换文件夹

71 changetable(ftp, str)72 behind_name =showdownloadfile(ftp)73

74 randomb = randint(0, len(behind_name)-1)75 while randomb: #在这个文件夹下随机下载几个

76 randomdownload(ftp, localpath, str)77 randomb -= 1

78 #切换目录下载(可能向下或者向上)

79 #viewtable(ftp)

80

81

82

83

84 def gettable(ftp): #获取目录结构

85 dir_del =[]86

87 table_dir ={}88 ftp.dir('.', dir_del.append) #根据文件目录,进行拆分。

89 for name indir_del:90 strname =str(name)91 temp = strname.split(' ')92 attrname =[]93 for j inrange(0,len(temp)):94 if temp[j] != '':95 attrname.append(temp[j])96 m = ' '.join(attrname[8:])97 if strname.startswith('d'):98 #print('文件夹:', m)

99 table_dir[m] = '文件夹'

100 else:101 #print('文件:', m)

102 table_dir[m] = '文件'

103 return table_dir #字典,key值是文件名,value是类型

104

105 defviewtable(ftp,str):106 #gettable(ftp) # 获取当前目录

107 changtimes = randint(1, 4) #随机切换几次目录

108 whilechangtimes:109 changtimes -= 1

110 folder_name =showfolderfile(ftp)111 print("当前目录下为:"+ftp.pwd())112 print("目录结构:")113 print(gettable(ftp))114 if len(folder_name) > 0: #有可供索引的文件夹

115 if ftp.pwd() == str: #为根目录,只能向下索引

116 print("向下索引后目录为:")117 randomf = randint(0, len(folder_name)-1)118 path = ftp.pwd()+folder_name[randomf]119 ftp.cwd(path)120 print("当前目录下为:"+ftp.pwd())121 print("目录结构:")122 print(gettable(ftp))123

124 else: #向上向下索引都可以

125 downorup = randint(0, 1)126 if downorup: #向下索引

127 print("向下索引后目录为:")128 randomf = randint(0, len(folder_name)-1)129 path = ftp.pwd()+folder_name[randomf]130 ftp.cwd(path)131 print("当前目录下为:"+ftp.pwd())132 print("目录结构:")133 print(gettable(ftp))134

135 else:136 print("向上索引后,目录为:")137 path = '../'

138 ftp.cwd(path)139 print("当前目录下为:"+ftp.pwd())140 print("目录结构:")141 print(gettable(ftp))142 else: #没有可供索引的文件夹,可以向上索引。

143 if ftp.pwd() !=str:144 print("向上索引后,目录为:")145 path = '../'

146 ftp.cwd(path)147 print("当前目录下为:"+ftp.pwd())148 print("目录结构:")149 print(gettable(ftp))150

151 defchangetable(ftp,str):152 folder_name =showfolderfile(ftp)153 if len(folder_name) > 0: #有可供索引的文件夹

154 if ftp.pwd() == str: #为根目录,只能向下索引

155 randomf = randint(0, len(folder_name)-1)156 path = ftp.pwd()+folder_name[randomf]157 ftp.cwd(path)158

159 else: #向上向下索引都可以

160 downorup = randint(0, 1)161 if downorup: #向下索引

162 randomf = randint(0, len(folder_name)-1)163 path = ftp.pwd()+folder_name[randomf]164 ftp.cwd(path)165

166 else:167 path = '../'

168 ftp.cwd(path)169 else: #没有可供索引的文件夹,可以向上索引。

170 if ftp.pwd() !=str:171 path = '../'

172 ftp.cwd(path)173 defftpmain(ip, port, username, passwd, localpath, userModel):174 #1.连接到ftp服务器

175 ftp =ftpconnect(ip, port, username, passwd)176 #2.开始交互

177 str =ftp.pwd()178 #print(str)

179 #usermodel 也可以是一个列表序列,让一个用户,执行多个操作。

180 cmdtimes = randint(1, 5) #这随机多次执行用户模式。

181 #downloadtimes = 3 # 多个文件多次下载

182 whilecmdtimes:183 cmdtimes -= 1

184 if userModel == 1: #浏览模式

185 viewtable(ftp, str)186 changetable(ftp, str)187 continue

188 if userModel == 2: #下载模式

189 randomdownload(ftp, localpath, str)190 changetable(ftp, str)191 continue

192 if userModel == 3: #同时下载多个文件模式

193 #while downloadtimes:

194 downloadfiles(ftp, localpath, str)195 changetable(ftp, str)196 #downloadtimes -= 1

197 continue

198 else: #错误处理机制

199 print('无法识别传递的模式编号:')200 break

201

202 ftp.quit()203

204

205 if __name__ == "__main__":206 agrvlist = sys.argv[1].split(',')207 ip =agrvlist[0]208 port = int(agrvlist[1])209 username = agrvlist[2]210 passwd = agrvlist[3]211 usermodel = int(agrvlist[4])212 ftpmain(ip, port, username, passwd, "/home/username/", usermodel)

View Code

从程序中我们可以看出,其实还是很简单的。主要是引入ftplib库。用pip就可以。

下面简单说一下,我在编程中主要遇到的问题:

1.区分ftp服务器里面的文件夹和文件。

这里是解决的方法:

1 def gettable(ftp): #获取目录结构

2 dir_del =[]3

4 table_dir ={}5 ftp.dir('.', dir_del.append) #根据文件目录,进行拆分。

6 for name indir_del:7 strname =str(name)8 temp = strname.split(' ')9 attrname =[]10 for j inrange(0,len(temp)):11 if temp[j] != '':12 attrname.append(temp[j])13 m = ' '.join(attrname[8:])14 if strname.startswith('d'):15 #print('文件夹:', m)

16 table_dir[m] = '文件夹'

17 else:18 #print('文件:', m)

19 table_dir[m] = '文件'

20 return table_dir #字典,key值是文件名,value是类型

View Code

主要是先获取服务器文件夹里面的详细信息,通过分析,利用python的数据结构来区分。

下面是我的分析过程:

这是ftp服务器主目录下,通过ftp.dir(),然后输出结果为:

['drwxrwxrwx    2 0        0            4096 Jul 04 21:17 hello', '-rw-------    1 1001     131             3 Jul 05 10:20 test', '-rwxrwxrwx    1 1000     1000      2840284 Apr 20  2016 test.ogg']

通过查阅发现:hello是文件夹,test和test.ogg是文件。

然后进一步查分,最后通过'd'来区分。

strname.startswith('d')

2.获取外部输入

这个程序不是直接编译通过的,而是要传递外部参数。利用sys库进行操作。通过控制台运行函数。

1 if __name__ == "__main__":2 agrvlist = sys.argv[1].split(',')3 ip =agrvlist[0]4 port = int(agrvlist[1])5 username = agrvlist[2]6 passwd = agrvlist[3]7 usermodel = int(agrvlist[4])

View Code

由于 外部参数都是以字符串形式传入,所以要进行格式转换操作。

3.限制下载速度。

这个功能在程序中没有实现。后来通过阅读关于网络的书籍,关于tcp的过程,其实是可以通过设置缓冲区的大小来模拟延迟的。当然这个下载速度服务器是由主导权的。

这个项目主要学到的东西在ftp服务器搭建中,放到下个随笔中。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值