1.文件目录

selector_FTP ——————

clientfile ——————  存放用户文件路径

selector_client.py——

selector_server.py——

serverfile —————— 存放服务器文件路径

注:实现的简约版的FTP,不支持断点续传、断点下载等操作

且只支持普通上传下载 用selector实现,支持多条客户端链接同时下载、上传 ,切勿多个客户端同时上传、下载同一个文件。

服务端

selector_server.py

def get(conn,cmd): 下载文件

def put(conn,cmd): 上传文件

def accept(sock, mask): selector 注册方法

def read(conn, mask): selector 注册方法

selector_server.py

def get(conn,cmd): 下载文件

def put(conn,cmd): 上传文件

def progress(recive_size,file_size,tips) 显示下载进度方法

例子:

clientfile 里面有一个3D.pdf  在客户端输入命令 put 3D.pdf  后 serverfile 文件夹下会有3D.pdf

serverfile 里面有一个test.zip  在客户端输入命令 get test.zip  后 clientfile  文件夹下会有test.zip

服务器端:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: wenjinLi
import selectors
import socket
import os,sys
import time
import errno
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
sel = selectors.DefaultSelector()def get(conn,cmd):if len(cmd.split()) > 1:filename = cmd.split()[1]file_path = '%s/serverfile/%s' % (BASE_DIR, filename) #文件路径print(file_path)if os.path.isfile(file_path): #判断文件是否存在client_file_size = 0file_size = os.stat(file_path).st_size #获得文件大小conn.send(str(file_size).encode()) #将文件大小传给客户端time.sleep(0.3)while True:with open(file_path, 'rb') as f:try:for line in f:client_file_size += len(line) #记录已经传送的文件大小conn.sendall(line)print(client_file_size, file_size)except IOError as e:if e.errno != errno.EAGAIN: # errno.EAGAIN 缓冲区满 等待下raiseelse:time.sleep(0.1) #等待0.1s进行下一次读取if client_file_size >= int(file_size): #文件传送完毕print('break')breakelse:conn.sendall('405'.encode())  # 文件不存在else:conn.sendall('401'.encode())  # 命令不存在,无法操作
def put(conn,cmd):filename = cmd.split()[1]filename = "%s/serverfile/%s" % (BASE_DIR, filename) #文件路径with open(filename, 'ab') as f:data = conn.recv(1024).decode()total_size = int(data)if total_size == '405' or total_size == '401': #文件不存在 或命令有误return Nonecurrent_size = 0while current_size <= total_size:try:recivesize = total_size - current_sizeif recivesize > 1024:recivesize = 1024data = conn.recv(recivesize)if not data: #客户端断开print('closing', conn)sel.unregister(conn)conn.close()breakcurrent_size += len(data)f.write(data)except IOError as e:if e.errno != errno.EAGAIN:raiseelse:time.sleep(0.1)print('接收完毕')def accept(sock, mask):conn, addr = sock.accept()  # Should be readyconn.setblocking(False)sel.register(conn, selectors.EVENT_READ, read)def read(conn, mask):data = conn.recv(1000)  # Should be readyif data:print(data)command_str = data.decode()print(command_str)if command_str.split()[0] == 'put':put(conn, command_str)elif command_str.split()[0] == 'get':get(conn,command_str)else:conn.send(b'404') # Hope it won't blockelse:print('closing', conn)sel.unregister(conn)conn.close()sock = socket.socket()
sock.bind(('localhost', 1112))
sock.listen(100)
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)while True:events = sel.select()for key, mask in events:callback = key.datacallback(key.fileobj, mask)

用户端:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: wenjinLi
import socket
import time
import os,sys
import errno
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
def get(s,command):'''下载'''if len(command.split()) == 2:s.send(command.encode()) #通知服务器 要上传文件了else:print('下载命令有误')filename = command.split()[1]filename = "%s/clientfile/%s" % (BASE_DIR, filename) #本地地址with open(filename, 'ab') as f:data = s.recv(1024)print(data)data = data.decode()total_size = int(data)if total_size == '405':print('文件不存在')return Nonecurrent_size = 0while current_size <= total_size:try:recivesize = total_size - current_sizeif recivesize > 1024:recivesize = 1024data = s.recv(recivesize)if not data:breakcurrent_size += len(data)progress(current_size, total_size, '下载中...') #打印进度print(current_size, total_size)f.write(data)except IOError as e:if e.errno != errno.EAGAIN:raiseelse:time.sleep(0.1) #若 系统缓存已满则等带0.1秒后开始print('接收完毕')
def put(s,command):'''上传'''if len(command.split()) == 2:s.send(command.encode()) #告诉服务器要上传文件else:print('上传命令有误')if len(command.split()) > 1:filename = command.split()[1]file_path = '%s/clientfile/%s' % (BASE_DIR, filename)print(file_path)if os.path.isfile(file_path):current_file_size = 0file_size = os.stat(file_path).st_sizes.send(str(file_size).encode())time.sleep(0.3)with open(file_path, 'rb') as f:try:for line in f:s.sendall(line)current_file_size += len(line)progress(current_file_size, file_size, '上传中...')print(current_file_size,file_size)except IOError as e:if e.errno != errno.EAGAIN:  # errno.EAGAIN 缓冲区满 等待下raiseelse:time.sleep(0.1)  # 等待0.1s进行下一次读取else:s.send('405'.encode())print('文件不存在')else:s.send('401'.encode())print('命令不存在')def progress(recive_size,file_size,tips):'''***代表加载 _____表示还未加载部分'''lensize = 100percent = float(recive_size) / float(file_size)recivenumber = '*' * int(percent * lensize)  # 已经加载的所占格数leftnumber = '_' * (lensize - int(percent * lensize))  # 未加载的所占格数sys.stdout.write('%s:%d%% [%s]\n' % (tips, percent * lensize, recivenumber + leftnumber))sys.stdout.flush()if __name__ == '__main__':HOST = 'localhost'PORT = 1112s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.connect((HOST,PORT))while True:msg = input('>>>请输入操作命令:').strip()if len(msg) == 0:continuecommand = msg.split()[0]if command == 'get':'''下载'''get(s,msg)elif command == 'put':'''上传'''put(s, msg)elif command == 'exit':print('成功退出')breakelse:continues.close()

转载于:https://www.cnblogs.com/nanfengxiaojin/p/6942243.html

python 之selectors 实现文件上传下载相关推荐

  1. Python + Paramiko实现sftp文件上传下载

    最近在测试服务器那块,看了下Paramiko模块,一直都是用FileZilla工具,想了想,持续集成,更新代码可以用Parmmiko完成,还是不错的 Paramiko是用python语言写的一个模块, ...

  2. python实现文件上传下载

    Python实现文件上传下载 环境准备: 1. 实验分两个文件,服务端(linux)和客户端(windows). 服务端运行环境:python2.x 客户端运行环境:python3.x 2. 使用了库 ...

  3. Django实战之文件上传下载

    项目介绍 最近学习django,通过文件上传下载这个小项目,总结下常用的知识点. 做这个案例我有以下需求: 1.要支持一次上传多个文件 2.支持上传后记录上传的数据以及列表展示 3.支持下载和删除文件 ...

  4. linux 安装上传文件,linux常用命令(二)文件上传下载及软件安装

    1.上传下载工具安装 (1)WINDOWS 到linux的文件上传及下载: windows下打开secureCRT,通过SSH连到⾄至远程linux主机: 上传下载工具安装命令:yum -y inst ...

  5. FTP编程实验——实现文件上传下载(基于Python3.7和PyQt5)

    目录 FTP编程实现文件上传下载(基于Python3.7和PyQt5) 一.实验目的 二.实验内容 三.实验步骤 (一)服务器端 (二)客户端 [1] 界面设计 [2] 生成布局代码 [3] 功能实现 ...

  6. 登峰造极的python requests完成接口文件上传的案例

    这篇文章主要介绍了python requests完成接口文件上传的案例,具有很好的参考价值,希望对大家有所帮助.一起跟随北凡过来看看吧 最近在准备一个公开课,主题就是利用不同的语言和不同的工具去实现文 ...

  7. 教你如何实现c#文件上传下载功能

    简单介绍一下c#文件上传下载功能实现. NuGet 安装SqlSugar Model文件下新建 DbContext 类 public class DbContext {public DbContext ...

  8. [C# 网络编程系列]专题十一:实现一个基于FTP协议的程序——文件上传下载器...

    引言: 在这个专题将为大家揭开下FTP这个协议的面纱,其实学习知识和生活中的例子都是很相通的,就拿这个专题来说,要了解FTP协议然后根据FTP协议实现一个文件下载器,就和和追MM是差不多的过程的,相信 ...

  9. SpringMVC整合fastdfs-client-java实现web文件上传下载

    为什么80%的码农都做不了架构师?>>>    版权声明:本文为博主原创文章,转载请标明出处(http://blog.csdn.net/wlwlwlwl015)Thanks. 目录( ...

  10. JavaWeb实现文件上传下载功能实例解析

    转:http://www.cnblogs.com/xdp-gacl/p/4200090.html JavaWeb实现文件上传下载功能实例解析 在Web应用系统开发中,文件上传和下载功能是非常常用的功能 ...

最新文章

  1. Qt 自定义信号与槽
  2. 【leetcode238】Product of Array Except Self
  3. 长期使用中型Access数据库的一点经验
  4. O太多,具体都代表什么呢?
  5. sql server 调用webservice
  6. 手把手教您如何识别翻新机子
  7. 通俗地讲清楚fit_transform()和transform()的区别
  8. 理解图像的傅里叶变换
  9. 同样是卖票,为啥阿里卖电影票就不卡?技术上做了啥???
  10. 无重复字符串的最长子串
  11. python的属性访问,python:如何访问函数的属性
  12. 在命令行中使用vs编译器
  13. html5小游戏抓包,wireshark抓包分析
  14. 前端安全——XSS攻击与防御原理详解
  15. linux安装smmo压缩包软件,Linux centos 安装rarlinux压缩软件 使有rarlinux
  16. ①变量、常量、数据类型解释 ②标识符命原则 ③sizeof使用原则 ④float型科学计数法 ⑤字符转换到ASCII表 ⑥\t 的使用意义【黑马程序员视频】
  17. android 获取本地图片路径
  18. Pdf 插入图片 | 指定位置插入图片 不改变原格式 直接操作 pdf
  19. android lint 安全检测,Android Lint检查
  20. Docker环境undertow线程数不足问题探究

热门文章

  1. Visual Studio2017 数据库架构比较
  2. C#Json数据交互
  3. HTML 第5章 Div+CSS布局技术
  4. [Bootstrap]7天深入Bootstrap(1)入门准备
  5. Response.ContentType 控制输出文件类型(讨论下载文件问题)
  6. java面向对象的基本概念
  7. 虚拟化发展历程及原理
  8. 2016中国大学生程序设计竞赛(长春)
  9. Android中Adapter之BaseAdapter使用
  10. Android设置分隔线