开发简单的FTP:

1. 用户登陆

2. 上传/下载文件

3. 不同用户家目录不同

4. 查看当前目录下文件

5. 充分使用面向对象知识

1、目录结构
zuoye-ftp
├── chenliang #用户chenliang的FTP根目录
├── download #所有用户下载的时候默认文件路径
├── lw #用户lw的FTP根目录
├── lzd #用户lzd的FTP根目录
├── wangjun #用户wangjun的FTP根目录
├── wdl #用户wdl的FTP根目录
├── xueli #用户xueli的FTP根目录
├── create-users.py #创建用户专用py文件
├── ros.zip #模拟上下载的测试文件ros.zip
├── socket_client.py #客户端文件
├── socket_server.py #服务端文件
├── user_data.bak #shelve文件
├── user_data.dat #shelve文件
└── user_data.dir #shelve文件

2、创建用户运行create-users.py,默认帐号密码是一致的。已有用户chenliang,lw,lzd,wangjun,wdl,xueli
3、创建的用户,在执行服务端的时候,自动会生成一个自己用户的FTP根目录,同时便于测试会复制ROS.zip到自己根目录
4、先运行socket_server.py,默认socket的服务端端口号为6969
5、再运行socket_client.py

create-users.py

  1. #!/usr/bin/env python
  2. #-*-coding:utf-8-*-
  3. #Author:lzd
  4. #创建用户名和密码,默认用户名和密码一致
  5. import shelve
  6. userlist=[]
  7. user_data=shelve.open("user_data")
  8. # for i in user_data.items():
  9. # print(i)
  10. print("当前已有的所有用户的用户名如下:")
  11. for i in user_data.keys():
  12. userlist.append(user_data[i])
  13. print(userlist)
  14. while True:
  15. username=input("请输入用户名\n")
  16. if username in userlist:
  17. print("用户名重复啦,请重新输入用户名!")
  18. continue
  19. else:
  20. password=input("请输入用户密码\n")
  21. break
  22. user_data[username]=password
  23. user_data.close()
  24. print("用户创建成功~!")

socket_server.py

  1. #!/usr/bin/env python
  2. #-*-coding:utf-8-*-
  3. #Author:lzd
  4. #服务器端
  5. import os
  6. gongzuopath=os.getcwd()
  7. # print(gongzuopath)
  8. import time
  9. #print(time.strftime("%Y%m%d%H%M%S",time.localtime()))
  10. import socket
  11. server = socket.socket()
  12. server.bind(('localhost',6969)) #绑定要监听端口
  13. server.listen() #监听
  14. import shutil
  15. import shelve
  16. userlist=[]
  17. user_data=shelve.open("user_data")
  18. for i in user_data.keys():
  19. userlist.append(user_data[i])
  20. if not os.path.exists(gongzuopath+r"/"+i):
  21. os.mkdir(gongzuopath+r"/"+i)
  22. if not os.path.exists(gongzuopath+r"/"+i+"/ros.zip"):
  23. shutil.copyfile(gongzuopath+r"/ros.zip",gongzuopath+r"/"+i+"/ros.zip")
  24. print("我要开始等电话了")
  25. while True:
  26. Flag = True
  27. conn, addr = server.accept() # 等电话打进来
  28. # conn就是客户端连过来而在服务器端为其生成的一个连接实例
  29. print(conn, addr)
  30. print("电话来了")
  31. while Flag:
  32. data = conn.recv(1024)
  33. print("recv:",data)
  34. if not data:
  35. print("client has lost...")
  36. break
  37. clientuser=data.decode("utf-8")
  38. if clientuser in userlist:
  39. conn.send("请输入用户密码".encode("utf-8"))
  40. data = conn.recv(1024)
  41. print("recv:",data)
  42. if not data:
  43. print("client has lost...")
  44. break
  45. if data.decode("utf-8")==user_data[clientuser]:
  46. conn.send("用户名密码验证成功".encode("utf-8"))
  47. while Flag:
  48. data = conn.recv(1024)
  49. print("recv:", data)
  50. if data=="choose3".encode("utf-8"):
  51. if ",".join(os.listdir(gongzuopath+r"/"+clientuser)).encode("utf-8"):
  52. conn.send(",".join(os.listdir(gongzuopath+r"/"+clientuser)).encode("utf-8"))
  53. else:
  54. conn.send("当前目录下为空".encode("utf-8"))
  55. elif data=="choose1".encode("utf-8"):
  56. conn.send("服务端准备接收文件".encode())
  57. data = conn.recv(1024).decode("utf-8") #收到文件大小,单位byte
  58. filesize=data
  59. print("recv:文件大小为", data)
  60. tmpdata="服务端准备接收大小为"+data+"的文件"
  61. conn.send(tmpdata.encode())
  62. serverfile=gongzuopath+r"/"+clientuser+"/"+time.strftime("%Y%m%d%H%M%S",time.localtime())
  63. f = open(serverfile, "wb")
  64. while str(os.stat(serverfile).st_size) != filesize:
  65. data=conn.recv(10240000)
  66. f.write(data)
  67. f.flush()
  68. else:
  69. conn.send("文件发送完毕".encode("utf-8"))
  70. elif data=="choose2".encode("utf-8"):
  71. if ",".join(os.listdir(gongzuopath + r"/" + clientuser)).encode("utf-8"):
  72. conn.send(",".join(os.listdir(gongzuopath + r"/" + clientuser)).encode("utf-8"))
  73. else:
  74. conn.send("当前目录下为空".encode("utf-8"))
  75. continue
  76. data = conn.recv(1024).decode("utf-8")
  77. print(data)
  78. if not data:
  79. continue
  80. print("recv:客户端要下载的文件名", data)
  81. fpath=gongzuopath+r"/"+clientuser+r"/"+data
  82. fpath_size = str(os.stat(fpath).st_size)
  83. f = open(fpath, "rb")
  84. filedata = f.read()
  85. conn.send(fpath_size.encode("utf-8"))
  86. conn.sendall(filedata)
  87. data = conn.recv(1024)
  88. print(data.decode("utf-8")) # 文件接收完毕
  89. elif data=="choose4".encode("utf-8"):
  90. Flag=False
  91. else:
  92. conn.send("用户名密码验证失败".encode("utf-8"))
  93. else:
  94. conn.send("输入的用户名不存在".encode())
  95.  
  96. server.close()

socket_client.py

  1. #!/usr/bin/env python
  2. #-*-coding:utf-8-*-
  3. #Author:lzd
  4. #客户端
  5. import socket
  6. import os
  7. gongzuopath=os.getcwd()
  8. # print(os.stat(gongzuopath+"/lzd/"+"ros.zip").st_size)
  9. client = socket.socket() #声明socket类型,同时生成socket连接对象
  10. client.connect(('localhost',6969))
  11. while True:
  12. username=input("请输入用户名\n")
  13. if len(username) == 0: continue
  14. client.send(username.encode("utf-8"))
  15. data=client.recv(1024)
  16. print(data.decode())
  17. if data.decode()=="请输入用户密码":
  18. password=input("")
  19. client.send(password.encode("utf-8"))
  20. data=client.recv(1024)
  21. print(data.decode())
  22. if data.decode()=="用户名密码验证失败":
  23. continue
  24. elif data.decode()=="用户名密码验证成功":
  25. while True:
  26. print("%s当前的工作目录为/%s"%(username,username))
  27. print("""
  28. 1、上传文件;
  29. 2、下载文件;
  30. 3、查看当前目录下的所有文件;
  31. 4、退出程序
  32. 请输入你想操作的数字?
  33. """)
  34. choose=input("")
  35. if choose=="":
  36. print("当前用户的工作目录下所有文件如下:")
  37. print(",".join(os.listdir(gongzuopath + r"/" + username)))
  38. fpath2=input("请输入你想上传到服务器的文件名,为便于测试,当前目录下有个1M的文件ros.zip\n")
  39. print("默认会在当前用户的目录下生成一个当前时间的文件。")
  40. if not fpath2:
  41. continue
  42. fpath=gongzuopath+r"/"+username+r"/"+fpath2
  43. fpath_size=str(os.stat(fpath).st_size)
  44. f=open(fpath,"rb")
  45. filedata=f.read()
  46. client.send("choose1".encode("utf-8"))
  47. data = client.recv(1024)
  48. print(data.decode("utf-8")) #服务器准备接收文件
  49. client.send(fpath_size.encode("utf-8"))
  50. data = client.recv(1024)
  51. print(data.decode("utf-8")) #服务端准备接收大小为%s的文件
  52. client.sendall(filedata)
  53. data = client.recv(1024)
  54. print(data.decode("utf-8")) # 文件发送完毕
  55. if choose=="":
  56. client.send("choose2".encode("utf-8"))
  57. data = client.recv(1024)
  58. print("您当前的工作目录下,所有的文件如下:")
  59. print(data.decode("utf-8")) # 显示当前工作目录下所有文件
  60. if data.decode("utf-8")=="当前目录下为空":
  61. continue
  62. print("您想下载哪个文件到本地?默认下载到当前脚本的工作目录的download目录")
  63. fpath2 = input("请输入你想下载的文件名\n")
  64. client.send(fpath2.encode("utf-8"))
  65. fpath = gongzuopath + r"/download/" + fpath2
  66. data = client.recv(1024).decode("utf-8")
  67. file_size=data
  68. print("您想下载的文件大小为:",data)
  69. f = open(fpath, "wb")
  70. while str(os.stat(fpath).st_size) != file_size:
  71. data = client.recv(10240000)
  72. f.write(data)
  73. f.flush()
  74. else:
  75. client.send("文件接收完毕".encode("utf-8"))
  76. print("文件接收完毕")
  77. if choose=="":
  78. client.send("choose3".encode("utf-8"))
  79. data = client.recv(1024)
  80. print("您当前的工作目录下,所有的文件如下:")
  81. print(data.decode("utf-8"))
  82. if choose=="":
  83. client.send("choose4".encode("utf-8"))
  84. client.close()
  85. exit()

第七周作业——简单FTP的更多相关文章

  1. 2017-2018-1 我爱学Java 第六七周 作业

    团队六七周作业 完善版需求规格说明书 制定团队编码规范 数据库设计 后端架构设计 TODOList 参考资料 完善版需求规格说明书 <需求规格说明书>初稿不足之处: 1.开发工具写错 2. ...

  2. 2018-2019-1 20189221 《Linux内核原理与分析》第七周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第七周作业 实验六 分析Linux内核创建一个新进程的过程 代码分析 task_struct: struct task ...

  3. 2017-2018-1 JAVA实验站 第六、七周作业

    2017-2018-1 JAVA实验站 第六.七周作业 详情请见团队博客

  4. 2017-2018-1 JaWorld 第六、七周作业

    2017-2018-1 JaWorld 第六.七周作业 修改需求规格说明书 上次的<需求规格说明书>初稿有哪些不足? 王译潇同学回答:   1. 引言和目的性考虑的不是很周全.   2. ...

  5. 2017-2018-1 20179205《Linux内核原理与设计》第七周作业

    <Linux内核原理与设计>第七周作业 视频学习及操作分析 创建一个新进程在内核中的执行过程 fork.vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_for ...

  6. 2019-2020-1 20199325《Linux内核原理与分析》第七周作业

    第七周作业 1.进程描述符task_struct数据结构(一) 为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息. struct task_struct数据结构很 ...

  7. 2019-2020-1 20199329《Linux内核原理与分析》第七周作业

    <Linux内核原理与分析>第七周作业 一.本周内容概述: 对Linux系统如何创建一个新进程进行追踪 分析Linux内核创建一个新进程的过程 二.本周学习内容: 1.学习进程的描述 操作 ...

  8. 2020-2021-1 20209307《Linux内核原理与分析》第七周作业

    这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)> 这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第七周作业> 这个作业的目标 & ...

  9. 1903021116—吉琛—Java第七周作业—客户类测试

    项目 内容 课程班级博客链接 19信计班 这个作业要求链接 第七周作业链接 博客名称 学号-姓名-Java第七周作业-客户类测试 要求 每道题要有题目,代码(使用插入代码,不会插入代码的自己查资料解决 ...

随机推荐

  1. LeetCode OJ:Search a 2D Matrix II(搜寻二维矩阵)

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  2. 网页宽高clientWidth clientHeight获得数值不对的问题

    当网页内容撑不满一屏时,通过以下代码获得整个网页高度会有问题 document.body.clientHeight;document.body.clientWidth; 得到的宽高不对,可能是因为ht ...

  3. Maven入门-2.Maven一些核心概念介绍

    1.Maven仓库2.Maven坐标3.Maven插件和目标4.Maven生命周期4.1 clean:清理项目4.2 default:构建项目(重要)4.3 site:建立项目站点 1.Maven仓库 ...

  4. oracle和sql server 比较

    Oracle   SQLServer   比较 字符数据类型  CHAR  CHAR  都是固定长度字符资料但oracle里面最大度为2kb,SQLServer里面最大长度为8kb 变长字符数据类型  ...

  5. C语言编程的两个工具:valgrind和core

    检查内存泄漏: valgrind --leak-check=full ./ecox_rws_helper 来检查内存泄漏 程序崩溃看错误: ulimit -c unlimited 然后执行程序,会在当 ...

  6. Dom4j下载及使用Dom4j读写XML简介(转)

    Dom4j下载及使用Dom4j读写XML简介 要使用dom4j读写XML文档,需要先下载dom4j包,dom4j官方网站在 http://www.dom4j.org/目前最新dom4j包下载地址:ht ...

  7. Android 仿微信朋友圈查看

    项目要做一个类似于这样的功能,就做了. 项目下载地址:http://download.csdn.net/detail/u014608640/9917626 一,看下效果: 二.activity类 pu ...

  8. 《Drools7.0.0.Final规则引擎教程》第4章 4.4 LHS简介&Pattern

    LHS简介 在规则文件组成章节,我们已经了解了LHS的基本使用说明.LHS是规则条件部分的统称,由0个或多个条件元素组成.前面我们已经提到,如果没有条件元素那么默认就是true. 没有条件元素,官方示 ...

  9. 服务器重装和配置:Ubuntu16.04 + Anaconda3 + GTX1080驱动 + CUDA8 + cuDNN + 常用工具安装

    前一篇[基于Ubuntu16.04的GeForce GTX 1080驱动安装,遇到的问题及对应的解决方法]是在机器原有系统上安装GPU驱动,后来决定备份数据后重装系统,让服务器环境更干净清爽. 1.安 ...

  10. 深入理解java虚拟机-第13章-线程安全与锁优化

    第十三章 线程安全与锁优化 线程安全 java语言中的线程安全 1 不可变.Immutable 的对象一定是线程安全的 2 绝对线程安全 一个类要达到不管运行时环境如何,调用者都不需要额外的同步措施, ...