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. win10卸载瑞星

    下载了一个软件,没有注意就不小心装上了瑞星这个流氓软件 百度N种办法并不能解决~ 我试过正常卸载.试过WIN自带卸载.试过重装再卸载 最后采取最傻瓜最暴力的办法 ctrl+alt+delete 打开任 ...

  2. 一个很好的JS,ASP二级下拉框联动。

    在我们制作网站会员注册信息时,一般会涉及到填写自己所在省/市,如果用input或textarea做成填写形式不太理想.所以大部分网站都会选择联动下来列表形式,做起来也不算很复杂,同时看上去也很轻松. ...

  3. Netty、NIO、多线程

    一:Netty.NIO.多线程? 时隔很久终于又更新了!之前一直迟迟未动也是因为积累不够,后面比较难下手.过年期间@李林锋hw发布了一个Netty5.0架构剖析和源码解读,看完也是收获不少.前面的文章 ...

  4. HDU5976 Detachment

    /* HDU5976 Detachment http://acm.hdu.edu.cn/showproblem.php?pid=5976 数论 等差数列 * * */ #include <cst ...

  5. 多个API接口

    青云客智能聊天机器人API 为保证接口稳定,API接口正式启用 api.qingyunke.com,www.qingyunke.com 如何更换API接口地址? 答:如果您的API接口是用在微信公众号 ...

  6. 洛谷——P1968 美元汇率

    https://www.luogu.org/problem/show?pid=1968#sub 题目背景 此处省略maxint+1个数 题目描述 在以后的若干天里戴维将学习美元与德国马克的汇率.编写程 ...

  7. html 页面刷新

    JS 脚本 方法1 setInterval 函数 定时局部刷新用到jQuery里面的setInterval方法, 该函数每隔一段时间请求一次数据,然后将请求结果返回给前端HTML实现刷新. setIn ...

  8. HDU 1788

    必须MARK下:任何时候都要保持清醒头脑,不要被题目绕了.. 其实就是求最小公倍数. #include <iostream> #include <cstdio> #includ ...

  9. (译)RabbitMQ ——“Hello World”

    原文地址:http://www.rabbitmq.com/tutorials/tutorial-one-dotnet.html 介绍 RabbitMQ是一个消息实体服务(broker):它接收及转发消 ...

  10. 零基础学python-7.7 字符串格式化方法(1)

    承接上一章节.我们这一节来说说字符串格式化的还有一种方法.就是调用format() >>> template='{0},{1} and {2}' >>> templ ...