import socket
import os,sys
BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 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.port = ('10.30.40.61',8080)
self.create_socket()
self.command_fanout()
def create_socket(self):
try:
self.sk = socket.socket()
self.sk.connect(self.port)
print('连接服务器成功!')
except Exception as e:
print('error:',e)
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)
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.sk.send(bytes(fileInfo,encoding='utf-8'))
recvStatus = self.sk.recv(1024)
print('recvStatus',recvStatus)
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.sk.send(contant)
hasSend += recv_size
s = str(int(hasSend/fileSize*100))+'%'
print('正在上传文件:'+fileName+' 已经上传:'+s)
print('%s文件上传完毕'%(fileName,))
else:
print('文件不存在')
def get(self,cmd,file):
pass
if __name__ == '__main__':
selectFtpClient()
###################################################################################################
import os
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
#os.path.dirname(os.path.abspath(__file__)):当前文件的绝对路径,适用于各种python的架构全局变量
import time
import socket
import selectors
'''
思路:
'''
class selectFtpServer:
def __init__(self):
self.dic = {}
self.hasReceived = 0
self.sel = selectors.DefaultSelector()
self.create_socket()
self.handle()
def create_socket(self):
server = socket.socket()
server.bind(('10.30.40.61',8080))
server.listen(5)
server.setblocking(False)
self.sel.register(server,selectors.EVENT_READ,self.accept)
print('服务端已开启,等待用户连接....')
def handle(self):
while True:
events = self.sel.select()
for key,mask in events:
callback = key.data
callback(key.fileobj,mask)
def accept(self,sock,mask):
conn,addr = sock.accept()
print('from %s %s connected'%addr)
conn.setblocking(False)
self.sel.register(conn,selectors.EVENT_READ,self.read) self.dic[conn] = {}
def read(self,conn,mask):
try:
if not self.dic[conn]:
data = conn.recv(1024)
cmd,filename,filesize = str(data,encoding='utf-8').split('|')
self.dic = {conn:{'cmd':cmd,'filename':filename,'filesize':int(filesize)}} if cmd == 'put':
conn.send(bytes('OK',encoding='utf-8')) if self.dic[conn]['cmd'] =='get':
file = os.path.join(BASE_DIR,'download',filename) if os.path.exists(file):
fileSize = os.path.getsize(file)
send_info = '%s|%s'%('YES',fileSize)
conn.send(bytes(send_info,encoding='utf-8'))
else:
send_info = '%s|%s'%('NO',0)
conn.send(bytes(send_info,encoding='utf-8'))
else:
if self.dic[conn].get('cmd',None):
cmd = self.dic[conn].get('cmd')
if hasattr(self,cmd):
func = getattr(self,cmd)
func(conn)
else:
print('error cmd!')
conn.close()
else:
print('error cmd!')
conn.close()
except Exception as e:
print('error',e)
self.sel.unregister(conn)
conn.close()
def put(self,conn):
fileName = self.dic[conn]['filename']
fileSize = self.dic[conn]['filesize']
path = os.path.join(BASE_DIR,'upload',fileName)
recv_data = conn.recv(1024)
self.hasReceived +=len(recv_data) with open(path,'ab') as f:
f.write(recv_data)
if fileSize ==self.hasReceived:
if conn in self.dic.keys():
self.dic[conn] = {}
print('%s上传完毕!'%fileName)
def get(self,conn): filename = self.dic[conn]['filename']
path = os.path.join(BASE_DIR,'download',filename)
if str(conn.recv(1024),'utf-8') == 'second_active':
with open(path,'rb') as f:
for line in f:
conn.send(line)
self.dic[conn] = {}
print('文件下载完毕!')
if __name__ == '__main__':
selectFtpServer()

基于selectors模块实现并发的FTP的更多相关文章

  1. SELECTORS模块实现并发简单版FTP

    环境:windows, python 3.5功能:使用SELECTORS模块实现并发简单版FTP允许多用户并发上传下载文件 结构:ftp_client ---| bin ---| start_clie ...

  2. python 并发编程 基于gevent模块实现并发的套接字通信

    之前线程池是通过操作系统切换线程,现在是程序自己控制,比操作系统切换效率要高 服务端 from gevent import monkey;monkey.patch_all() import geven ...

  3. 基于socketserver模块实现并发的套接字(tcp、udp)

    tcp服务端:import socketserver class MyHandler(socketserver.BaseRequestHandler): def handle(self): #通信循环 ...

  4. IO模型《七》selectors模块

    一 了解select,poll,epoll IO复用:为了解释这个名词,首先来理解下复用这个概念,复用也就是共用的意思,这样理解还是有些抽象, 为此,咱们来理解下复用在通信领域的使用,在通信领域中为了 ...

  5. day33 网络编程之线程,并发以及selectors模块io多路复用

    io多路复用 selectors模块 概要: 并发编程需要掌握的知识点: 开启进程/线程 生产者消费者模型!!! GIL全局解释器锁(进程与线程的区别和应用场景) 进程池线程池 IO模型(理论) 1 ...

  6. python 全栈开发,Day44(IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)

    昨日内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yield,greenlet 遇到IO gevent: 检测到IO,能够使用greenlet实现自动切换,规避了IO阻 ...

  7. (IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)

    参考博客: https://www.cnblogs.com/xiao987334176/p/9056511.html 内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yi ...

  8. 并发编程之IO模型比较和Selectors模块

    主要内容: 一.IO模型比较分析 二.selectors模块 1️⃣ IO模型比较分析 1.前情回顾: 上一小节中,我们已经分别介绍过了IO模型的四个模块,那么我想大多数都会和我一样好奇, 阻塞IO和 ...

  9. Python selectors实现socket并发

    selectors模块 此模块允许基于选择模块原语构建高级别和高效的I / O多路复用. 鼓励用户使用此模块,除非他们想要精确控制使用的os级别的原语. 注:selectors也是包装了select高 ...

随机推荐

  1. 洛谷P3807 【模板】卢卡斯定理_组合数学模板

    Code: #include<cstdio> using namespace std; typedef long long LL; const int maxn=1000000+2; LL ...

  2. maven构建本地jar包到本地仓库

    maven命令: mvn:install:install-file -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=1.0 -Dpackaging ...

  3. 《你又怎么了我错了行了吧》【Alpha】Scrum meeting 5

    第五天 日期:2019/6/18 前言: 第5次会议在女生宿舍召开 冲刺第5天,对所有工作做了总结.继续完善编码工作. 1.1 今日完成任务情况以及明天任务安排 姓名 当前阶段任务 下一阶段任务 刘 ...

  4. 实战:一、使用mongo做一个注册的小demo

    思路:1.使用mongoose 进行 数据库的链接 2.使用Schema来进行传输字段的定义 3.安装koa-router进行数据处理4.安装koa-bodyparser 进行post数据交互5.解决 ...

  5. Linux常用命令last的使用方法详解

    http://www.jb51.net/article/120140.htm 最近在学习linux命令,学习到了last命令,发现很多同学对last命令不是很熟悉,last命令的功能列出目前与过去登入 ...

  6. J - Borg Maze

    J - Borg Maze 思路:bfs+最小生成树. #include<queue> #include<cstdio> #include<cstring> #in ...

  7. spring boot的几种配置类型

    1.spring boot的几种配置类型 1)基本配置,spring自动读取的,全都在application.yml里配置,spring会自动读取这个配置文件 2)个性化配置:比如配置intercep ...

  8. [HTML5]构建离线web应用程序

    1.检查浏览器是否支持缓存 if(window.applicationCache){ //TODO } 2.在html中加入manifest特性 <html manifest="app ...

  9. HDU 2815

    特判B不能大于等于C 高次同余方程 #include <iostream> #include <cstdio> #include <cstring> #includ ...

  10. 用户体验之如何优化你的APP

    用户体验,速度为王,来几个优化APP“速度”的建议. 1.后台执行 毋庸多言,已是通常做法. 一般在执行下载任务时让其在后台运营,让用户有精力去做别的事情. 后端加载 2.提前显示 客户端与WEB的数 ...