今天把做的ftp服务器过程总结一下,先看看要求

一.需求

1. 用户加密认证

2. 允许同时多用户登录

3. 每个用户有自己的家目录 ,且只能访问自己的家目录

4. 对用户进行磁盘配额,每个用户的可用空间不同

5. 允许用户在ftp server上随意切换目录cd

6. 允许用户查看当前目录下文件ls

7. 允许上传put和下载get文件,保证文件一致性

8. 文件传输过程中显示进度条

附加实现的功能:

1.实现服务器端文件删除,创建、删除目录

2.查看当前账户状态

3.实现断点续传

二.实现过程解析

1.客户端在登录的时候,密码不能用明文,以保证连接的安全性。以我现在的水平也就是把密码用hashlib里的md5转成密文一下。不过这个过程可以最后在做,前期调试过程可以用明文。

2.a使用socketserver做多并发来保证多个用户同时登录。我在socketserver里演示了socketserver的多并发的使用。

b在服务器端db文件夹内存有各个账户的文件。文件用josn的格式存储了账户的信息。

{"user_id":"admin","password":"","totle_space":100000000,"stat":false}

c账户内有个key:used_space是每次登陆时候生成的,在每次put操作和rmdir/remove后都会重新获取已用空间的值。最初用的是os.stat().st_size获取,但获取不到文件夹的占用空间。做了个这样的函数

 def get_path_size(self,path):
size = 0
for root, dirs, files in os.walk(path):
for f in files:
size += os.path.getsize(os.path.join(root, f))
return size

get_size

用这个方法,在文件量比较大的时候效率会比较低,高效的方法还没想好,看看以后还能改不!

3.在服务器端有个User的文件夹,文件夹内有各个用户的子文件夹。用户可以在客户端内进行目录的切换。这里是个很重要的地方:

a.用os.popen或者os.system()来执行cd的指令,是个深坑(特别是在linux内,一运行,就重新启动个terminal,然后就关闭了)

b.如果用chdir()的话,其实是改变了socketserver的工作目录,要是chdir('root')就相当有了root用户的权利,绝对不能用。

c.所以要切换目录,也就是不能切换,我在cmd的字典里加了个user_path的值,put、get都是在这个目录下进行的

d.每次登录后,直接进入该用户的路径:,每次用cd切换路径时,改变cmd_dic['user_path']的值。,刚好cd后有个空格,把空格后的字符赋值给cmd_dic['filename'],在服务器端根据这个值是'..'还是具体的路径进行相对应的操作。

e.在进行cd..时,应该注意最终只能到用户的家目录下。

f.在用os.popen('ls').read()时,返回的是该运行的.py所在文件夹下的文件,应该加上cmd_dic['user_path']的路径。

4.在conf文件夹下把所有的指令集做一个文件。把所有的操作对应的指令都存在这个文件内。这个指令集应该在服务器端,在登陆后发送给客户端。(这个暂未实现)

5.在实现put功能时,用了tkinter.filedialog弹窗选择文件的功能。

 import tkinter.filedialog
file = tkinter.filedialog.askopenfilename()
print(file)

弹窗选择文件

打印输出的就是文件的路径,但是有个问题还不知道原因,这里获取的文件路径的分隔符用的是'/'(系统是windows)。

C:\Users\Aaron\AppData\Local\Continuum\anaconda3\python.exe D:/python/homework/homework_ftp/ftp_client/test.py
C:/Users/Aaron/Desktop/UnderstandingGIL.pdf
注意下方的运行结果,文件分隔符用的是'/'
Process finished with exit code 0

运行结果

还有,这个tkiner的对话框在pycharm内单独调试的过程没什么问题,但是放在客户端的代码内每次运行完对话框不自行关闭,手动关闭就会卡死然后报出python未响应的错误(不关闭程序倒是能正常运行)在terminal内也不行。在不知道是不是库里的文件有问题。

6.在显示进度条的时候,思路是这样的:

a.由于每次发送接收都是逐行发送的,就会有filesize和receivedsize,两个一除,在乘100后取整就好(当时忘记了×100,由于是个百分数取整以后一直都是0)

    b.进度条显示是这样的

 import sys,time
for i in range(50):
sys.stdout.write("#")
sys.stdout.flush()
time.sleep(0.1)

进度条

    c.如果在每次接收时都显示一遍进度,会有很多重复的数据,我做了个判断,如果进度变化,就flush一遍,否则不再输出。

三.文件结构

程序分为上图中的结构,其实core中的main里涵盖了几乎所有的功能,功能多了以后在修改时候过于繁琐,其实应该把各个功能封装好另存在core文件夹下,再导入到main中(主要时偷懒了,因为开始写程序的时候是第一个功能就是写在main里的,后面就没改)。

后期可以更改的部分:

1.把main程序分解

2.改进进度条的显示

3.修改tkiner的对话框卡死的bug

4.把指令集放在server端

最后,把项目的代码放在云盘上了!代码地址,提取码:fvso

Python之ftp服务器的更多相关文章

  1. 助手系列之python的FTP服务器

    电脑的OS是Win7,Python版本是2.7.9,安装了pip 因为python没有内置可用的FTP SERVER,所以先选一个第三方的组件安装上,这里我选的是pyftpdlib pip insta ...

  2. python开发ftp服务器第一天(pyftpdlib)

    学习了大约快一个月的python,现在开始有意识做一些项目.(我的新书<Python爬虫开发与项目实战>出版了,大家可以看一下样章) 据我了解,python现在更多的是用于自动化运维方面, ...

  3. python 搭建ftp服务器

    代码示例: # coding: utf-8 import os from pyftpdlib.authorizers import DummyAuthorizer from pyftpdlib.han ...

  4. python搭建ftp服务器

    1 # coding: utf-8 import os from pyftpdlib.authorizers import DummyAuthorizer from pyftpdlib.handler ...

  5. Python向FTP服务器上传文件

    上传 代码示例: #!/usr/bin/python # -*- coding:utf-8 -*- from ftplib import FTP ftp = FTP() # 打开调试级别2, 显示详细 ...

  6. python实现FTP服务器

    https://www.cnblogs.com/huangxm/p/6274645.html

  7. Python一秒搭建ftp服务器,帮助你在局域网共享文件【华为云技术分享】

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...

  8. Python一秒搭建ftp服务器,帮助你在局域网共享文件

    "老板 来碗面" "要啥面?" "内牛满面.." 最近项目上的事情弄得人心累,本来是帮着兄弟项目写套入口代码,搞着搞着就被拉着入坑了.搞开发 ...

  9. Python黑科技:6行代码轻松搭建FTP服务器

    Python 黑科技 六行代码轻松搭建个人FTP服务器 什么是FTP服务器? FTP (File Transfer Protocol) 是一个用于客户端与服务器之间文件的协议.利用FTP我们就能做到在 ...

随机推荐

  1. laravel框架容器管理

    来自http://www.cnblogs.com/chy1000/p/7072936.html 本文面向php语言的laravel框架的用户,介绍一些laravel框架里面容器管理方面的使用要点.文章 ...

  2. 黄聪:谷歌验证 (Google Authenticator) 的实现原理是什么?

    著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:徐小花链接:http://www.zhihu.com/question/20462696/answer/18731073来源: ...

  3. linux git pull/push时提示输入账号密码之免除设置

    1.先cd到根目录,执行git config --global credential.helper store命令 [root@iZ25mi9h7ayZ ~]# git config --global ...

  4. [UE4]字体材质

    一.准备好一个字体文件,直接拖放到内容浏览器 二.创建一个名为testFontMaterial的UserWidget,添加一个TextBlock到默认的CanvasPanel.Font Family: ...

  5. 20145319 《网络渗透》MS08_067安全漏洞

    20145319 <网络渗透>MS08_067安全漏洞 一 实验内容 了解掌握metasploit平台的一些基本操作,能学会利用已知信息完成简单的渗透操作 了解漏洞MS08_067的相关知 ...

  6. sql使用实例

    将另一表中的合计值保存到指定字段,并将空值赋0 update ShopInfo set JLRunningWater =(select COALESCE(sum(v.TotalMoney),0) as ...

  7. shell脚本(二)

              shell脚本(二)——变量 一.定义:用来存放各种数据,编程语言组成部分 变量的命名规则: 变量名由数字 字母下划线组成 必须以字母或者下划线开头 不能使用shell里面的关键词 ...

  8. 用户名、密码等15个常用的js正则表达式

    本文收集整理了15个常用的javaScript正则表达式,其中包括用户名.密码强度.整数.数字.电子邮件地址(Email).手机号码.身份证号.URL地址. IPv4地址. 十六进制颜色. 日期. Q ...

  9. 205. jetcache:你需要知道的小技巧

    [视频&交流平台] àSpringBoot视频:http://t.cn/R3QepWG à SpringCloud视频:http://t.cn/R3QeRZc à Spring Boot源码: ...

  10. spring梳理