python使用selector模块编写FTP
server
import os
import socket
import time
import selectors
BASE_DIR = os.path.dirname(os.path.abspath(__file__)) class selectFtpServer(object): def __init__(self):
self.dic = {}
self.hasReceived = 0
self.sel = selectors.DefaultSelector()
self.create_socket()
self.handler() def create_socket(self):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("127.0.0.1", 8885))
server.listen(5)
self.sel.register(server, selectors.EVENT_READ, self.accept)
print("服务端已开启,等待用户连接...") def handler(self):
while True:
events = self.sel.select()
for key, mask in events:
call_back = key.data
call_back(key.fileobj, mask) def accept(self, server, mask):
conn, addr = server.accept()
print("from %s %s connected" % addr)
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)}}
print(self.dic)
if cmd == 'put':
conn.send(bytes("OK", encoding='utf8')) 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='utf8'))
else:
send_info = '%s|%s' % ('NO', 0)
conn.send(bytes(send_info, encoding='utf8'))
else:
if self.dic[conn].get('cmd', None):
print(self.dic[conn].get('cmd'))
cmd = self.dic[conn].get('cmd')
print(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):
self.hasReceived = 0
fileName = self.dic[conn]['filename']
fileSize = self.dic[conn]['filesize']
path = os.path.join(BASE_DIR, "upload", fileName)
while self.hasReceived < fileSize:
recv_data = conn.recv(1024)
self.hasReceived += len(recv_data) with open(path, 'wb') 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__':
ftp = selectFtpServer()
client
import socket
import time
import os BASE_DIR = os.path.dirname(os.path.abspath(__file__)) class selectFtpClient(): def __init__(self):
self.createSocket()
self.command_out() def createSocket(self):
try:
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.client.connect(("127.0.0.1", 8885))
print('连接FTP服务器成功!')
except Exception as e:
print("error: ", e) def command_out(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 get(self, cmd, file):
pass 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.client.send(bytes(fileInfo, encoding='utf8'))
recvStatus = self.client.recv(1024)
print('recvStatus', recvStatus)
hasSend = 0
if str(recvStatus, encoding='utf8') == "OK":
with open(file, 'rb') as f:
while fileSize > hasSend:
contant = f.read(1024)
recv_size = len(contant)
self.client.send(contant)
hasSend += recv_size
s = str(int(hasSend / fileSize * 100)) + "%"
print("正在上传文件:" + fileName + " 已经上传:" + s)
print('%s文件上传完毕' % (fileName,))
else:
print('文件不存在') if __name__ == '__main__':
c = selectFtpClient()
python使用selector模块编写FTP的更多相关文章
- 使用Python的requests模块编写请求脚本
requests模块可用来编写请求脚本. 比如,使用requests的post函数可以模拟post请求: resp = requests.post(url, data = content) url即为 ...
- python使用ftplib模块实现FTP文件的上传下载
python已经默认安装了ftplib模块,用其中的FTP类可以实现FTP文件的上传下载 FTP文件上传下载 # coding:utf8 from ftplib import FTP def uplo ...
- python之模块ftplib(FTP协议的客户端)
# -*- coding: utf-8 -*- #python 27 #xiaodeng #python之模块ftplib(FTP协议的客户端) #需求:快速进行ftp上传 ,下载,查询文件 from ...
- 【循序渐进学Python】10.模块和包
1.导入模块 任何Python程序都可以作为模块导入,只要Python解释器能找到我们定义的模块所在位置即可,一般来讲,在一个模块被导入时,Python解释器会按照下面的步骤进行搜索: 在当前所在目录 ...
- python之mysqldb模块安装
之所以会写下这篇日志,是因为安装的过程有点虐心.目前这篇文章是针对windows操作系统上的mysqldb的安装.安装python的mysqldb模块,首先当然是找一些官方的网站去下载:https:/ ...
- python的库有多少个?python有多少个模块?
这里列举了大概500个左右的库: ! Chardet字符编码探测器,可以自动检测文本.网页.xml的编码. colorama主要用来给文本添加各种颜色,并且非常简单易用. Prettytable主 ...
- Python中Selenium模块的使用
目录 Selenium的介绍.配置和调用 Selenium的配置 Selenium的调用 Selenium的使用 定位 定位元素的使用 定位下拉标签元素 在iframe框架之间切换 上传文件 Webd ...
- linux下python调用c模块
在C调用Python模块时需要初始化Python解释器,导入模块等,但Python调用C模块却比较简单,下面还是以helloWorld.c 和 main.py 做一说明: (1)编写C代码,hel ...
- python基础——使用模块
python基础——使用模块 Python本身就内置了很多非常有用的模块,只要安装完毕,这些模块就可以立刻使用. 我们以内建的sys模块为例,编写一个hello的模块: #!/usr/bin/env ...
随机推荐
- mybatis分页插件Mybatis_PageHelper 简单案例
源码地址(官网,文档) 使用条件: 支持mybatis 3.1.0+ sql 解析工具(jsqlparser.jar) 下载 Mybatis_PageHelper 版本随意,反正我用的5.0.0 m ...
- 2019.01.17 bzoj1853: [Scoi2010]幸运数字(容斥+dfs)
传送门 搜索菜题,然而第一次没有注意然后爆longlonglong longlonglong了. 题意:称所有数位由6,86,86,8组成的数为幸运数字,问一个一个区间[l,r][l,r][l,r]中 ...
- 2018.10.31 bzoj4737: 组合数问题(lucas定理+容斥原理+数位dp)
传送门 这是一道让我重新认识lucaslucaslucas的题. 考虑到lucaslucaslucas定理: (nm)≡(n%pm%p)∗(npmp)\binom n m \equiv \binom ...
- 牛客训练六:海啸(二维树状数组+vector函数的使用)
题目链接:传送门 思路: 二维树状数组, vector(first,last)函数中assign函数相当于将first中的函数清空,然后将last中的值赋值给first. 参考文章:传送门 #incl ...
- s4-2 ALOHA 协议
多路访问协议 随机访问协议(Random Access) 特点:站点争用信道,可能出现站点之间的冲突 典型的随机访问协议 • ALOHA协议 • CSMA协议 • CSMA/CD协议(以太网采 ...
- c#编程模仿的1stopt界面
* Levenberg-Marquardt法 (LM)+ 通用全局优化算法(Universal Global Optimization - UGO) * Quasi-Newton法 (BFGS)+ 通 ...
- python3.4连接mysql5.7数据库增删改查
#!/usr/bin/env python # -*- coding:utf-8 -*- # __author__ = "blzhu" """ pyt ...
- IntelliJ IDEA 2017版 编译器使用学习笔记(七) (图文详尽版);IDE快捷键使用;IDE代码重构(编写高质量代码)
一.重构 重构变量:将语义模糊的变量名称改为更易理解的名称 修改变量名称,快键键 shift + F6 (输入要改的名字,所有位置相同的名字都会改变) 重构方法 ...
- python中的分号
很多编程语言是以分号作为一行代码的的结束标志,但是在Python中不是这样的,而是靠缩进来识别程序结构. Python中一行代码以分号结束,并不是必须的,准确来说是不被推荐的,因为加上分号就是画蛇添足 ...
- 使用 WLST 和节点管理器来管理服务器
使用节点管理器启动计算机上的服务器 WLST 可以连接至在任何计算机上运行的节点管理器,并能够在此计算机上启动一个或多个 WebLogic Server 实例.要通过此技术使用 WLST 和节点管理器 ...