python之路之io多路复用

 

  1、实现io多路复用利用select

s1同时接受三个客户端(开启了三个服务器端口)

 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 
 4 import socket
 5 import select
 6 
 7 sk = socket.socket()
 8 sk.bind(('127.0.0.2', 9001))
 9 sk.listen()
10 
11 sk1 = socket.socket()
12 sk1.bind(('127.0.0.2', 9002))
13 sk1.listen()
14 
15 sk2 = socket.socket()
16 sk2.bind(('127.0.0.2', 9003))
17 sk2.listen()
18 
19 inputs = [sk, sk1, sk2]
20 while True:
21 
22     # [sk, sk1, sk2]select 内部自动监听sk1,sk,sk2三个对象,一旦某个句柄
23 
24     # 如果有人连接sk1,sk2
25     # r_list = [sk1,sk2]
26     r_list, w_list, e_list = select.select(inputs, [], [], 1)
27     # 1,是等待1秒的意思
28     for sk in r_list:
29         conn, address = sk.accept()
30         conn.sendall(bytes('hello', encoding='utf-8'))
31         conn.close()
32     for sk in e_list:
33         inputs.remove(sk
s1
 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 import socket
 4 
 5 
 6 obj = socket.socket()
 7 obj.connect(('127.0.0.2', 9001))
 8 
 9 content = str(obj.recv(1024), encoding='utf-8')
10 print(content)
11 
12 obj.close()
c1
 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 import socket
 4 
 5 
 6 obj = socket.socket()
 7 obj.connect(('127.0.0.2', 9002))
 8 
 9 content = str(obj.recv(1024), encoding='utf-8')
10 print(content)
11 
12 obj.close()
c2
 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 import socket
 4 
 5 
 6 obj = socket.socket()
 7 obj.connect(('127.0.0.2', 9003))
 8 
 9 content = str(obj.recv(1024), encoding='utf-8')
10 print(content)
11 
12 obj.close()
c3

  2、实现io多路的复用利用select

s1中只有一个服务器端口,底层用select,类似与,同时接三个电话,开免提,谁说话回答谁

 

 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 
 4 import socket
 5 import select
 6 
 7 sk1 = socket.socket()
 8 sk1.bind(('127.0.0.2', 9000))
 9 sk1.listen()
10 
11 inputs = [sk1]
12 while True:
13 
14     # r_list 中一开始只有服务器sk1,小军连接时,会把小军加入到inputs
15 
16     r_list, w_list, e_list = select.select(inputs, [], inputs, 1)
17     # 1,是等待1秒的意思
18     print('正在监听的socket对象%d' % len(inputs))
19     print(r_list)
20     for sk1_or_conn in r_list:
21         # 每一个连接对象
22         if sk1_or_conn == sk1:
23             conn, address = sk1_or_conn.accept()
24             inputs.append(conn)
25         else:
26             try:   # 有老用户发消息了
27                 data_bytes = sk1_or_conn.recv(1024)
28                 data_str = str(data_bytes,encoding='utf-8')
29                 sk1_or_conn.sendall(bytes(data_str+'', encoding='utf-8'))
30             except Exception as ex:
31                 inputs.remove(sk1_or_conn)
server
 1 # 只需重复运行三次即可
 2 #!/usr/bin/env python
 3 # -*- coding: utf-8 -*-
 4 import socket
 5 
 6 
 7 obj = socket.socket()
 8 obj.connect(('127.0.0.2', 9000))
 9 
10 while True:
11     inp = input('>>>>')
12     obj.sendall(bytes(inp, encoding='utf-8'))
13     ret = str(obj.recv(1024), encoding='utf-8')
14     print(ret)
15 
16 obj.close()
c3(当三个客户端)

  3、io多路复用socketserver

 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 import socketserver
 4 
 5 
 6 class MyServer(socketserver.BaseRequestHandler):
 7     def handle(self):
 8         conn = self.request  # request 不要加括号,加括号显示不出来东西,
 9         conn.sendall(bytes('欢迎来到梦幻西游', encoding='utf-8'))
10         while True:
11             ret_bytes = conn.recv(1024)
12             ret_str = str(ret_bytes, encoding='utf-8')
13             if ret_str == 'q':
14                 break
15             conn.sendall(bytes(ret_str + "", encoding='utf-8'))
16 
17 
18 if __name__ == '__main__':
19     server = socketserver.ThreadingTCPServer(('127.0.0.2', 1324), MyServer)
20     server.serve_forever()
socketserver
 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 
 4 
 5 import socket
 6 
 7 
 8 obj = socket.socket()
 9 obj.connect(('127.0.0.2', 1324))
10 
11 # 阻塞
12 re_bytes = obj.recv(1024)
13 ret_str = str(re_bytes, encoding='utf-8')
14 print(ret_str)
15 while True:
16     inp = input('请输入要发送的内容:')
17     if inp == 'q':
18         obj.sendall(bytes(inp, encoding='utf-8'))
19         break
20     else:
21         obj.sendall(bytes(inp, encoding='utf-8'))
22         ret = str(obj.recv(1024), encoding='utf-8')
23 
24         print(ret)
25 
26 obj.close()
client

 

  4、io多路复用select

 

outputs的使用,inputs的使用

 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 
 4 import socket
 5 import select
 6 
 7 sk1 = socket.socket()
 8 sk1.bind(('127.0.0.2', 9000))
 9 sk1.listen()
10 
11 inputs = [sk1]
12 outputs = []
13 message_dict = {}
14 
15 while True:
16 
17     # r_list 中一开始只有服务器sk1,小军连接时,会把小军加入到inputs
18 
19     r_list, w_list, e_list = select.select(inputs, outputs, inputs, 1)
20     # 1,是等待1秒的意思
21     print('正在监听的socket对象%d' % len(inputs))
22     print(r_list)
23     for sk1_or_conn in r_list:
24         # 每一个连接对象
25         if sk1_or_conn == sk1:
26             # 表示有新用户连接
27             conn, address = sk1_or_conn.accept()
28             inputs.append(conn)
29             message_dict[conn] = []  # 建立了一个字典{小军:[]}
30         else:
31             try:   # 有老用户发消息了
32                 data_bytes = sk1_or_conn.recv(1024)
33             except Exception as ex:
34                 inputs.remove(sk1_or_conn)
35             else:
36                 # 用户正常发消息
37                 data_str = str(data_bytes, encoding='utf-8')
38                 message_dict[sk1_or_conn].append(data_str)  # {小军:1233}
39                 outputs.append(sk1_or_conn)  # [小军]
40     # 谁发消息就会在w_list中显示。
41     for conn in w_list:
42         recv_str = message_dict[conn][0]
43         del message_dict[conn][0]
44         conn.sendall(bytes(recv_str + '', encoding='utf-8'))
45         outputs.remove(conn)
46 
47     for sk in e_list:
48         inputs.remove(sk)
s1
 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 import socket
 4 
 5 
 6 obj = socket.socket()
 7 obj.connect(('127.0.0.2', 9000))
 8 
 9 while True:
10     inp = input('>>>>')
11     obj.sendall(bytes(inp, encoding='utf-8'))
12     ret = str(obj.recv(1024), encoding='utf-8')
13     print(ret)
14 
15 obj.close()
c1

 

posted @ 2018-04-04 22:10  keepsummer  阅读(141)  评论(0编辑  收藏  举报