Python模拟FTP文件服务器的操作方法
作者:Rookie_Max 发布时间:2022-11-11 19:53:04
标签:python,ftp,服务器
分为服务端和客户端,要求可以有多个客户端同时操作。
客户端可以查看服务器文件库中有什么文件。
客户端可以从文件库中下载文件到本地。
客户端可以上传一个本地文件到文件库。
使用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文件服务器的操作方法网站的支持!
来源:https://blog.csdn.net/Rookie_Max/article/details/104351750


猜你喜欢
- 最近没事刚好联系下vue+springboot前段后分离的项目、用上了图片上传功能、记录一下。前端待提交的表单部分代码<el-form
- 目录结构:client:#!/usr/bin/env python# -*-coding:utf-8 -*-import socket, s
- 本文实例为大家分享了python实现随机漫步的具体代码,供大家参考,具体内容如下编写randomwalk类from random impor
- 根据教程实现了读取csv文件前面的几行数据,一下就想到了是不是可以实现前面几列的数据。经过多番尝试总算试出来了一种方法。之所以想实现读取前面
- 一、前言今天分享一个Python 制作透明背景的电子印章的代码,代码是通过网络获得并整理的,大家可以参考和学习。二、步骤解析代码我已调试过了
- 描述filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。该接收
- 有很多程序运行时间比较长,如果不将运行过程输出将很难判断程序运行的时间。下边这段程序将按照上图所示的格式输出程序运行进程、已用时间、剩余时间
- 什么是MySql数据库?通常意义上,数据库也就是数据的集合,具体到计算机上数据库可以是存储器上一些文件的集合或者一些内存数据的集合。我们通常
- 由于项目是thinkPHP做后端框架,一直以来都是多页面的后端路由,想使用火热的webpack有点无从下手(原谅我太菜,而且推广vue只有我
- 数据格式:(polygon.txt) 里面含有2个多边形,一行是一个点 0.085, 0.834, 0.024, 0.744, 0, 0.6
- strip()方法返回所有字符从开始及字符串的末尾(默认空格字符)被去除后的字符串的一个副本。语法以下是strip()方法的语法
- 钉钉SDK对接sdk还是遇到不少问题的钉钉python版SDK文档地址:https://dingtalk-sdk.readthe
- 关键字:js验证表单大全,用JS控制表单提交 ,javascript提交表单:目录:1:js 字符串长度限制、判断字符长度 、js限制输入、
- 由于业务需要,要查询客户的ip地址,将部分地区的客户过滤出来,开始想到使用ip数据库,发现读取纯真数据库的难度对我来说有些大,而我目前的时间
- mouseDown事件和mouseUp事件 大家知道,mouseDown事件和mouseUp事件的组合就是click事件,但是如果在链接上按
- 本方法是基于文本密度的方法,最初的想法来源于哈工大的《基于行块分布函数的通用网页正文抽取算法》,本文基于此进行一些小修改。约定:
- 几乎是一夜之间,微信小游戏《羊了个羊》火了。?这个依靠寻找相同元素消除方块的小游戏,凭借其“变态级别&rdquo
- 本文实例讲述了PHP中round()函数对浮点数进行四舍五入的方法。分享给大家供大家参考。具体方法如下:语法:round(x,prec)参数
- python在不同层级目录import模块的方法使用python进行程序编写时,经常会调用不同目录下的模块及函数。本篇博客针对常见的模块调用
- 发现这个也是偶然,在测试的时候发现的,因此问题还发现一个bug。蛮有意思~ 假如输入http://www.aspxhome.com的话,在