Python模拟FTP文件服务器的操作方法


Posted in Python onFebruary 18, 2020

分为服务端和客户端,要求可以有多个客户端同时操作。

客户端可以查看服务器文件库中有什么文件。
客户端可以从文件库中下载文件到本地。
客户端可以上传一个本地文件到文件库。
使用print在客户端打印命令输入提示,引导操作

服务端

# 导入相关模块
from socket import *
from multiprocessing import Process
import signal, os, time
# 绑定IP地址
IP = "127.0.0.1"
# 绑定端口
PORT = 8888
ADDR = (IP, PORT)
# 绑定服务器的指定目录
DIR = "/home/max/ftp"
# 处理查看文件请求
def browse(c):
 # 列表方式查看文件
 list = os.listdir("%s" % DIR)
 # 按通信协议格式组织数据
 msg = "B " + ";".join(list)
 # 发送到客户端
 c.send(msg.encode())
# 处理客户端下载文件请求
def download(c, file):
 # 判断文件是否存在且是否是文件
 if file in os.listdir(DIR) and os.path.isfile("%s/%s" % (DIR, file)):
  # 打开文件
  f = open("%s/%s" % (DIR, file), "rb")
  # 发送下载代码,告知客户端进入"D"
  c.send(("D %s " % file).encode())
  # 等待客户端先进入"D"模式下的recv阻塞函数
  time.sleep(0.1)
  # 循环发送文件
  while True:
   data = f.read(1000)
   if not data:
    # 设置间隔,等待文件传输完整
    time.sleep(0.1)
    # 约定的信息让客户端退出接收循环
    c.send(b"finished")
    break
   c.send(data)
  f.close()
 # 否则按协议格式发送错误代码
 else:
  c.send(b"D fileerror ")
# 处理客户端上传文件请求
def upload(c, file):
 # 创建文件
 f = open("%s/%s" % (DIR, file), "wb")
 # 循环接收文件
 while True:
  data = c.recv(1024)
  # 收到约定的信息退出循环
  if data == b"finished":
   break
  f.write(data)
 f.close()
# 处理客户端退出请求
def login_out(c):
 # 按协议格式组织信息
 msg = "O closed "
 # 发给客户端的recv_msg进程
 c.send(msg.encode())
def deal(c):
 # 发送代码告知客户端连接成功
 c.send(b"K ")
 while True:
  # 循环接收客户端请求,约定通信协议为"* ** ****"格式
  msg = c.recv(1024)
  # 如果客户端崩了,解除该子进程
  if not msg:
   break
  # 解析请求
  req = msg.decode().split(" ", 2)
  # 处理查看文件请求,跳入browse函数
  if req[0] == "B":
   browse(c)
  # 处理客户端下载文件请求,跳入download函数
  elif req[0] == "D":
   download(c, req[1])
  # 处理客户端上传文件请求,跳入upload函数
  elif req[0] == "U":
   upload(c, req[1])
  # 处理客户端退出请求,跳入login_out函数
  elif req[0] == "O":
   login_out(c)
   # 跳出循环,结束子进程
   break
# 主程序,父进程用于接收客户端请求并循环创建子进程,子程序处理请求
def main():
 # 创建tcp套接字
 s = socket()
 # 绑定服务器地址
 s.bind(ADDR)
 # 设置监听套接字
 s.listen()
 # 处理僵尸进程
 signal.signal(signal.SIGCHLD, signal.SIG_IGN)
 while True:
  # 连接客户端
  c, addr = s.accept()
  # 创建子进程,用以处理客户端请求,跳入deal函数
  p = Process(target=deal, args=(c,))
  # 子程序开始执行
  p.start()
if __name__ == '__main__':
 main()

客户端

# 导入相关模块
from socket import *
import os, sys, time
# 绑定服务端IP地址
IP = "127.0.0.1"
# 绑定服务端端口
PORT = 8888
ADDR = (IP, PORT)
# 收到约定的信息退出循环
# 发送消息进程
def send_msg(s):
 # 等待接收进程先运行到"K"分支
 time.sleep(0.1)
 while True:
  try:
   # 输入指令
   data = input(">>>")
  except:
   # 客户端错误,向服务端发送O
   data = "O"
  if data == "B": # 查看目录
   msg = "B "
   s.send(msg.encode())
  elif data == "D": # 下载文件
   # 输入想要下载的文件
   want = input("download ? file:")
   msg = "D %s " % want
   s.send(msg.encode())
  elif data == "U": # 上传文件
   file = input("upload ? file:")
   # 判断文件是否在客户端文件所在的目录且是文件
   if file in os.listdir(os.getcwd()) and os.path.isfile("%s/%s" % (os.getcwd(), file)):
    msg = "U %s " % file
    s.send(msg.encode())
    f = open("%s" % file, "rb")
    # 等待服务端进入upload的recv阻塞函数
    time.sleep(0.1)
    while True:
     data = f.read(1000)
     if not data:
      # 设置间隔,等待文件传输完整
      time.sleep(0.1)
      # 约定的信息让客户端退出接收循环
      s.send(b"finished")
      break
     s.send(data)
    f.close()
    print("upload succussfully")
   # 否则按协议格式显示错误代码
   else:
    print("file not exist\ninput BDUO to forward\n", end="")
  elif data == "O": # 断开连接
   msg = "O "
   s.send(msg.encode())
   sys.exit()
  # 指令错误
  else:
   print("input error")

# 接收消息进程
def recv_msg(s):
 while True:
  data = s.recv(1024)
  # 解析数据
  msg = data.decode().split(" ", 2)
  if msg[0] == "K": # 登录成功反馈
   print(
    "login in successfully\ninput B to browse,D to download,U to upload,O to login out")
  elif msg[0] == "B": # 查看目录反馈
   # 如果文件库不为空
   if msg[2]:
    print("files:", msg[2], "\n>>>", end="")
   else:
    print("files: no files", "\n>>>", end="")
  elif msg[0] == "D":
   # 服务端文件不存在
   if msg[1] == "fileerror":
    print("file not exist\ninput BDUO to forward\n>>>", end="")
    continue
   # 服务端文件存在
   else:
    f = open("%s" % msg[1], "wb")
    while True:
     data = s.recv(1024)
     # 收到约定的信息退出循环
     if data == b"finished":
      break
     f.write(data)
    f.close()
    print("download successfully\n>>>", end="")
  elif msg[0] == "O": # 收到来自发送消息进程发送到服务端的断开请求
   # 进程退出并打印提示
   sys.exit("login out successfully")

# 主程序
def main():
 # 创建tcp套接字
 s = socket()
 # 连接服务端
 s.connect(ADDR)
 # 创建多进程,子进程用于发送消息,父进程用于接收消息
 pid = os.fork()
 if pid < 0:
  print("system error")
 # 子进程
 elif pid == 0:
  send_msg(s)
 # 父进程
 else:
  recv_msg(s)
if __name__ == '__main__':
 main()

总结

以上所述是小编给大家介绍的Python_模拟FTP文件服务器的操作方法,希望对大家有所帮助,也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python中的filter()函数的用法
Apr 27 Python
利用python获取当前日期前后N天或N月日期的方法示例
Jul 30 Python
详解Python进程间通信之命名管道
Aug 28 Python
python爬虫获取多页天涯帖子
Feb 23 Python
Python中if elif else及缩进的使用简述
May 31 Python
virtualenv 指定 python 解释器的版本方法
Oct 25 Python
在pandas多重索引multiIndex中选定指定索引的行方法
Nov 16 Python
Python lxml解析HTML并用xpath获取元素的方法
Jan 02 Python
python ChainMap的使用和说明详解
Jun 11 Python
Django的CVB实例详解
Feb 10 Python
Django实现将一个字典传到前端显示出来
Apr 03 Python
Python Django获取URL中的数据详解
Nov 01 Python
git查看、创建、删除、本地、远程分支方法详解
Feb 18 #Python
Python使用urllib模块对URL网址中的中文编码与解码实例详解
Feb 18 #Python
python实现根据给定坐标点生成多边形mask的例子
Feb 18 #Python
python有序查找算法 二分法实例解析
Feb 18 #Python
Python连接SQLite数据库并进行增册改查操作方法详解
Feb 18 #Python
Python 解析pymysql模块操作数据库的方法
Feb 18 #Python
Anaconda3+tensorflow2.0.0+PyCharm安装与环境搭建(图文)
Feb 18 #Python
You might like
一个程序下载的管理程序(四)
2006/10/09 PHP
php循环检测目录是否存在并创建(循环创建目录)
2011/01/06 PHP
php实现算术验证码功能
2018/12/05 PHP
combox改进版 页面原型参考dojo的,比网上jQuery的那些combox功能强,代码更小
2010/04/15 Javascript
js变换显示图片的实例
2013/04/16 Javascript
JS 按钮点击触发(兼容IE、火狐)
2013/08/07 Javascript
处理及遍历XML文档DOM元素属性及方法整理
2013/08/23 Javascript
jQuery实现的图片分组切换焦点图插件
2015/01/06 Javascript
基于JavaScript实现窗口拖动效果
2017/01/18 Javascript
angular+webpack2实战例子
2017/05/23 Javascript
node.js基于fs模块对系统文件及目录进行读写操作的方法详解
2017/11/10 Javascript
Vue最新防抖方案(必看篇)
2019/10/30 Javascript
javascript实现支付宝滑块验证码效果
2020/07/24 Javascript
python版飞机大战代码分享
2018/11/20 Python
Python3 使用cookiejar管理cookie的方法
2018/12/28 Python
Python3显示当前时间、计算时间差及时间加减法示例代码
2019/09/07 Python
详解pycharm连接远程linux服务器的虚拟环境的方法
2020/11/13 Python
总结30个CSS3选择器
2017/04/13 HTML / CSS
CSS3.0实现霓虹灯按钮动画特效的示例代码
2021/01/12 HTML / CSS
微信小程序canvas实现水平、垂直居中效果
2020/02/05 HTML / CSS
中国最大的名表商城:万表网
2016/08/29 全球购物
法国二手手袋、手表和奢侈珠宝购物网站:Collector Square
2018/07/05 全球购物
Lentiamo比利时:便宜的隐形眼镜
2020/02/14 全球购物
思想品德自我鉴定
2013/10/12 职场文书
幼儿园新学期寄语
2014/01/18 职场文书
销售人员自我评价
2014/02/01 职场文书
党课知识竞赛主持词
2014/04/01 职场文书
《去年的树》教学反思
2014/04/11 职场文书
客运企业隐患排查工作方案
2014/06/06 职场文书
社区党员志愿服务活动方案
2014/08/18 职场文书
关于读书的演讲稿600字
2014/08/27 职场文书
2014医学院领导干部四风对照检查材料思想汇报
2014/09/16 职场文书
教师自查自纠工作情况报告
2014/10/29 职场文书
大学生入党自传2015
2015/06/26 职场文书
Python3.10的一些新特性原理分析
2021/09/15 Python
vue3 自定义图片放大器效果的示例代码
2022/07/23 Vue.js