selectors 模块完成文件上传下载功能
Posted maoxinjueluo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了selectors 模块完成文件上传下载功能相关的知识,希望对你有一定的参考价值。
1 ############ server端 2 3 import selectors,socket,time,pickle,os,struct 4 ip_port = (‘192.168.43.182‘,8080) 5 buffer_size = 1024 6 back_log = 5 7 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 8 9 class SelectorsServer: 10 def __init__(self): 11 self.conn_dict = {} 12 self.has_put = 0 13 self.has_get = 0 14 self.sel = selectors.DefaultSelector() ## 创建selectors 对象 15 self.creat_socket() 16 self.handle() ## 监听 17 18 def creat_socket(self): ## 创建socket 对象 19 sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 20 sock.bind(ip_port) 21 sock.listen(back_log) 22 sock.setblocking(False) 23 self.sel.register(sock,selectors.EVENT_READ,self.accept) 24 25 def handle(self): ## 监听事件 26 while 1: ## 循环监听 27 events = self.sel.select() 28 for key,mask in events: 29 callback = key.data 30 callback(key.fileobj,mask) 31 32 33 def accept(self,sock,mask): ### 连接 34 conn,addr = sock.accept() 35 # print(conn) 36 print(‘连接成功。。。‘) 37 conn.setblocking(False) 38 self.sel.register(conn,selectors.EVENT_READ,self.read) ## 给conn注册 39 self.conn_dict[conn] = {} ## 标识conn连接完成 40 41 def read(self,conn,mask): ## 通信循环 42 if not self.conn_dict[conn]: ## 第一次进来 43 res = conn.recv(buffer_size) 44 res = pickle.loads(res) 45 action = res[‘action‘] 46 filename = res[‘filename‘] 47 filename = os.path.join(BASE_DIR,‘files‘,filename) 48 print(‘ok‘) 49 conn.sendall(b‘ready‘) ## 取到动作和文件名 50 self.conn_dict[conn] = {‘action‘:action,‘filename‘:filename} 51 if hasattr(self, action): 52 func = getattr(self,action) 53 func(conn) 54 else: ## 不是第一次进来 55 if self.conn_dict[conn][‘action‘] == ‘put‘: ## 上传 56 self.put_append(conn) ## 追加 57 58 def put_append(self,conn): 59 f = open(self.conn_dict[conn][‘filename‘],‘ab‘) 60 if self.has_put < self.conn_dict[conn][‘file_size‘]: 61 data = conn.recv(buffer_size) ## 接收正文 62 f.write(data) 63 self.has_put += len(data) 64 f.close() 65 66 def put(self,conn): ## 上传 67 print(‘能运行到put‘,conn) 68 69 file_size = conn.recv(4) 70 file_size = struct.unpack(‘i‘,file_size) 71 self.conn_dict[conn][‘file_size‘] = file_size 72 f = open(self.conn_dict[conn][‘filename‘],‘wb‘) 73 if self.has_put < file_size: 74 data = conn.recv(buffer_size) ## 接收正文 75 f.write(data) 76 self.has_put += len(data) 77 f.close() 78 79 80 def get(self): ## 下载 81 pass 82 83 84 85 86 87 if __name__ == ‘__main__‘: 88 SelectorsServer()
1 ############ client端 2 import socket,os,pickle,struct 3 ip_port = (‘192.168.43.182‘,8080) 4 buffer_size = 1024 5 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 6 print(BASE_DIR) 7 class SelectorsClient: 8 def __init__(self): 9 self.creat_socket() 10 self.handle() 11 12 def handle(self): 13 while 1: 14 cmd_res = input(‘>>>:‘) 15 action,filename = cmd_res.split() 16 send_dict = { 17 ‘action‘:action, 18 ‘filename‘:filename 19 } 20 self.client.sendall(pickle.dumps(send_dict)) ## 传一个字典 21 recv_data = self.client.recv(buffer_size) 22 print(recv_data) 23 if hasattr(self,action): 24 func = getattr(self,action) 25 func(filename) 26 27 28 ## put 123.png 29 def put(self,filename): ## 上传操作 30 with open(filename,‘rb‘) as f: 31 data = f.read() 32 length = len(data) 33 file_size = struct.pack(‘i‘,length) 34 self.client.sendall(file_size) ## 发送文件大小 35 self.client.sendall(data) ## 发送正文 36 37 38 39 ## get 123.png 40 def get(self): ## 下载操作 41 pass 42 43 def creat_socket(self): 44 self.client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 45 self.client.connect(ip_port) 46 47 if __name__ == ‘__main__‘: 48 SelectorsClient()
以上是关于selectors 模块完成文件上传下载功能的主要内容,如果未能解决你的问题,请参考以下文章
Day388.Selector&Pipe&fileLock文件锁&Path&Files&AsynchronousFileChannel异步通道 -NIO(代码片
runtime????????????selector???????????????IMP???????????????????????????????????????????????????(代码片