selectors 模块完成文件上传下载功能
2021-03-22 23:24
标签:files main eve color recv lis input 对象 监听事件 selectors 模块完成文件上传下载功能 标签:files main eve color recv lis input 对象 监听事件 原文地址:https://www.cnblogs.com/maoxinjueluo/p/12695135.html 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 ‘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()