import selectors
import socket
import os,time BASE_DIR = os.path.dirname(os.path.abspath(__file__))
'''
知识点:
self.dic = {conn}、监听过程中 events 对象为活动列表。 总结:
read()不应该写死时间,重新监听执行到read()时通过dic分割、状态保持,
以判断选择执行代码逻辑, ''' class selectFtpServer:
# sel = selectors.DefaultSelector()
def __init__(self):
self.ip_port=('127.0.0.1',8885)
self.sel=selectors.DefaultSelector()#根据平台选择最佳的IO多路机制,比如linux就会选择epoll
self.hasReceived=0
self.dic = {}
self.create_sock()
self.handle() # 创建socket对象
def create_sock(self):
server = socket.socket()
server.bind(('localhost', 1234))
server.listen(100)
server.setblocking(False)
# 实例变量进行注册,sever与实例方法accept绑定
self.sel.register(server, selectors.EVENT_READ, self.accept)
print('server is running, waiting for connect') def handle(self):
while True:
events = self.sel.select() # [server,conn1,conn2]活动列表
for key, mask in events:
callback = key.data # 触发accept
callback(key.fileobj, mask) # accept(new_socket,mask) def accept(self,sock, mask):
print('登录服务端---')
conn, addr = sock.accept() # Should be ready
print('accepted', conn, 'from', addr)
conn.setblocking(False)
self.sel.register(conn, selectors.EVENT_READ, self.read) self.dic[conn]={}#conn赋值 def read(self,conn, mask): try:
if not self.dic[conn]: data = conn.recv(1024)
try:
cmd, filename, filesize = str(data.decode("utf-8")).split("|")
self.dic[conn] = {"cmd": cmd, "filename": filename, "filesize": filesize, "hasReceived": 0}
except Exception as e: cmd, filename = str(data.decode("utf-8")).split("|")
self.dic[conn] = {"cmd": cmd, "filename": filename,"filesize": os.path.getsize(os.path.join(BASE_DIR, "load", filename)),"hasSended": 0} if cmd=='put':#上传
conn.send('ok'.encode('utf8')) if cmd=='get':#下载
conn.send(str(self.dic[conn]['filesize']).encode('utf8'))
else:
if self.dic[conn].get('cmd',None):
cmd =self.dic[conn].get('cmd')
if hasattr(self,cmd):
func=getattr(self,cmd)
func(conn,mask)#反射命令分发
else:
print('error')
except Exception as e:
print(e,conn,'断开连接')
conn.close()
self.sel.unregister(conn) def put(self,conn,mask):
filename=self.dic[conn]['filename']
filesize = self.dic[conn]['filesize'] path = os.path.join(BASE_DIR, "upload", filename) data = conn.recv(1024)
conn.send("success".encode("utf-8"))
self.dic[conn]['hasReceived'] += len(data)
with open(path, "ab") as f:
f.write(data)
if self.dic[conn]['hasReceived'] == self.dic[conn]['filesize']:
self.dic[conn] = {}
print("上传结束") def get(self, conn, mask): filename = self.dic[conn]['filename']
path = os.path.join(BASE_DIR, "load", filename) with open(path, "rb") as f:
f.seek(self.dic[conn]["hasSended"], 0)
data = f.read(1024)
conn.send(data)
self.dic[conn]['hasSended'] += len(data)
if self.dic[conn]['hasSended'] == self.dic[conn]["filesize"]:
self.dic[conn] = {}
print("下载结束")
time.sleep(0.5) if __name__ == "__main__":
selectFtpServer()

import os, time, sys

BASE_DIR = os.path.dirname(os.path.abspath(__file__))

import socket

class selectFtpClient:
def __init__(self):
self.args = sys.argv # 命令行参数
if len(self.args)>1:
self.port=(self.args[1],int(self.args[2]))
else:
self.ip_port=('127.0.0.1',8885)
self.create_socket()
self.command_fanout() def create_socket(self):
try:
self.sock = socket.socket()
self.sock.connect(self.port)
print("连接FTP成功!")
except Exception:
print("连接失败!") def command_fanout(self):
while True:
cmd = input(">>>").strip()
if cmd == "exit()":
break
cmd, file = cmd.split()
if hasattr(self, cmd):
func = getattr(self, cmd)
func(cmd, file)#put('put',path)
else:
print('调用错误!') # 上传
def put(self, cmd, file):
if os.path.isfile(file):#判断文件是否存在
fileName = os.path.basename(file)#取名字
fileSize = os.path.getsize(file)#取大小
fileInfo = "%s|%s|%s" % (cmd, fileName, fileSize)#管道符打包
self.sock.send(bytes(fileInfo, encoding="utf-8"))#引起server变化
recvStatus = self.sock.recv(1024)
hasSend = 0
if str(recvStatus, encoding="utf-8") == 'ok':
with open(file, "rb") as f:
while fileSize > hasSend:
contant = f.read(1024)
recv_size = len(contant)
self.sock.send(contant)
hasSend += recv_size
s = str(int(hasSend / fileSize * 100)) + "%"
print("正在上传文件:" + fileName + " 已经上传: " + s)
time.sleep(0.5)
print("%s文件上传完毕" % (fileName,))
else:
print("文件不存在") # 下载
def get(self, cmd, file): fileInfo = "%s|%s" % (cmd, file)
self.sock.send(bytes(fileInfo, encoding="utf-8"))
filesize = int(self.sock.recv(10).decode("utf-8")) f = open(file, "ab")
i = 0
while i < filesize:
self.sock.send("ok".encode("utf-8"))
data = self.sock.recv(10)
f.write(data)
i += len(data)
s = str(int(i / filesize * 100)) + "%"
print("正在上传文件:" + file + " 已经下载: " + s) print("下载完成")
f.close() if __name__ == "__main__":
selectFtpClient()

python selectors模块实现 IO多路复用机制的上传下载的更多相关文章

  1. python实现批量远程执行命令及批量上传下载文件

    #!/usr/bin/env python # -*- coding: utf- -*- # @Time : // : # @Author : xuxuedong # @Site : # @File ...

  2. java中io流实现文件上传下载

    新建io.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" page ...

  3. python实现socket上传下载文件-进度条显示

    在python的socket编程中,可以实现上传下载文件,并且在下载的时候,显示进度条,具体的流程如下图所示: 1. 服务器端代码如下: [root@python 519]# cat server.p ...

  4. Python/ selectors模块及队列

    Python/selectors模块及队列 selectors模块是可以实现IO多路复用机制: 它具有根据平台选出最佳的IO多路机制,比如在win的系统上他默认的是select模式而在linux上它默 ...

  5. IO多路复用机制(转)

    1.简介 希望通过这篇文章,可以回答以下几个问题? 为什么需要IO多路复用? 什么是IO多路复用机制? IO多路复用的机制该怎么使用? epoll比select/poll相比,优势在哪里? 在了解I/ ...

  6. python之模块ftplib(实现ftp上传下载代码)

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #python之模块ftplib(实现ftp上传下载代码) #需求:实现ftp上传下载代码(不含错误处理) f ...

  7. python使用ftplib模块实现FTP文件的上传下载

    python已经默认安装了ftplib模块,用其中的FTP类可以实现FTP文件的上传下载 FTP文件上传下载 # coding:utf8 from ftplib import FTP def uplo ...

  8. python中使用paramiko模块并实现远程连接服务器执行上传下载

    paramiko模块 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接. 因此,如果需要使用SSH从一个平台连接到另外一个平台,进行一系 ...

  9. python paramiko模拟ssh登录,实现sftp上传或者下载文件

    Python Paramiko模块的安装与使用详解 paramiko是短链接,不是持续链接,只能执行你设定的shell命令,可以加分号执行两次命令. http://www.111cn.net/phpe ...

随机推荐

  1. ES6深入浅出-4 迭代器与生成器-5.科班 V.S. 培训

    为什么要学用不到的东西 科班是把你未来一二十年用的东西都给你入个门 做前端 三年后一定要再学一门语言. 买一本图解算法 培训讲究的是技能,只能满足3到5年,而不是术,学术学的是你未来10年甚至20年用 ...

  2. (十四)访问标志 Access_flags

    一.概念 上一章节讲到了常量池,如下图,常量池之后便是访问标志acess_flags,占2个字节(u2). 二.例子 编写一个接口. public interface Test{ public fin ...

  3. (一)eclipse Dynamic web project 工程目录以及文件路径问题

    如图,我创建了一个work 的web project,当工程完成之后,部署在服务器上时,整个work工程会被打包成一个war包,如 除了可以在eclipse上运行,工具会帮我们自动部署在服务器上之外, ...

  4. ConfigMap介绍

    来源 ConfigMap API资源用来保存key-value pair配置数据,这个数据可以在pods里使用,或者被用来为像controller一样的系统组件存储配置数据.虽然ConfigMap跟S ...

  5. union all 关键字的应用(合并两个查询结果集到同一个结果集)

    在此对于数据库中 union all 关键字的功能和用法进行简单的使用介绍. 这是我工作中的一个需求: 有两个 A表 和B表. A表的数据: B表的数据: 现在有这样一个需求,让他一次性的全部查出来. ...

  6. linux语句

    查看网卡 ip addr ifconfig

  7. 025 Android 带进度条的对话框(ProgressDialog)

    1.ProgressDialog介绍 ProgressDialog可以在当前界面弹出一个置顶于所有界面元素的对话框,同样具有屏蔽其他控件的交互能力,用于提示用户当前操作正在运行,让用户等待: 2.应用 ...

  8. PAT(B) 1034 有理数四则运算(Java)

    题目链接:1034 有理数四则运算 (20 point(s)) 题目描述 本题要求编写程序,计算 2 个有理数的和.差.积.商. 输入格式 输入在一行中按照 a1/b1 a2/b2 的格式给出两个分数 ...

  9. Arm-Linux 移植 FFMPEG库 + x264

      背景: ffmpeg 中带有264的解码,没有编码,需要添加x264.libx264是一个自由的H.264编码库,是x264项目的一部分,使用广泛,ffmpeg的H.264实现就是用的libx26 ...

  10. jwt 无状态分布式授权

    基于JWT(Json Web Token)的授权方式 JWT 是JSON风格轻量级的授权和身份认证规范,可实现无状态.分布式的Web应用授权: 从客户端请求服务器获取token, 用该token 去访 ...