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. 强大的JQuery链式操作风格

    实例代码 <style type="text/css"> #menu {width: 300px;} .has_children {background:#555;co ...

  2. VUEX 总结

    What is Vuex? vuex是一个专为Vue.js应用程序开发的状态管理模式.他采用集中式储存管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变换 VUEX并不限制你的代 ...

  3. python中的各个包的安装,用pip安装whl文件

    在安装之前,一直比较迷惑究竟如何用,安装完后,发现竟然如此简单 首先我一般用的是python27,官网下载python27msi安装window7 64位后,已经自带了Pip 和 easy_insta ...

  4. 【Codeforces 469B】Chat Online

    [链接] 我是链接,点我呀:) [题意] [题解] 因为你的朋友的时间是固定的. 你完全可以开一个tag[50]的数组,如果tag[i]=1说明i时刻你的基友在线(扫描基友的时间就能 得到 然后你在判 ...

  5. BA-传感器

    01.室内温度传感器 壁装,西门子,QAA2061D 1.默认范围:温度0-50℃,湿度0-100% 2.供电方式:24vac 3.穿线方式:4芯屏蔽线 02.风管温度传感器 西门子,QAM2120. ...

  6. 设置编码格式为utf8

    response.setCharacterEncoding("UTF-8"); 在Servlet2.3中是不行的,至少要2.4版本才可以,如果低于2.4版本,可以用如下办法: re ...

  7. Python Study (01) 之 特殊方法

    Python深入:特殊方法和多范式 Python是一切皆对象,意思就是python的天生就是个"纯面向对象语言"呀. 但是!!! Python还是一个多范式语言(multi-par ...

  8. AOP经典2种配置演示样例

    第一种: 使用aop指定切面aspect. <bean id="LogAdvice" class="com.thinkmore.framework.monitor. ...

  9. 【翻译自mos文章】怎么startup/shutdown PDB?

    怎么startup/shutdown PDB? 来源于: 12c: How to Startup/Shutdown PDB's? (文档 ID 1592247.1) 适用于: Oracle Datab ...

  10. 在C 函数中保存状态:registry、reference和upvalues

    在C函数中保存状态:registry.reference和upvalues      C函数能够通过堆栈来和Lua交换数据,但有时候C函数须要在函数体的作用域之外保存某些Lua数据.那么我们想到全局变 ...