Selector 模型

1.服务器端:

import selectors
import socket

sel = selectors.DefaultSelector() #生成一个select对象

def accept(sock, mask): #有新链接进来
    conn, addr = sock.accept()  # Should be ready
    print('accepted', conn, 'from', addr)
    conn.setblocking(False) #设置为非阻塞模式
    sel.register(conn, selectors.EVENT_READ, read) #把conn注册到sel中,此时回调函数是read,
    # 新链接如果有活动,就调read函数。因为此时客户端可能还没有开始发数据呢,所以把Conn也加入检测列表。
    #如果再有活动,就会调用read了。

def read(conn, mask):
    data = conn.recv(1024)  # Should be ready
    if data:
        print('echoing', repr(data), 'to', conn)
        conn.send(data)  # Hope it won't block

    else:
        print('closing', conn)
        sel.unregister(conn) #取消注册
        conn.close() #关闭链接

sock = socket.socket()
sock.bind(('localhost', 9998))
sock.listen(100)
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept) #让sel监听sock,只要来一个新链接,就调accept函数
                                                 #先把sock对象自己加入到检测列表里面。

while True:
    events = sel.select() #这里的select调用的可能是select或者是epoll,取决于系统支持的是哪个。
#默认是阻塞的,有活动连接就返回活动的连接列表。第一次如果有活动,肯定是新链接进来了。新链接进来后,就会调用accept函数。
    for key, mask in events: #只要有活动的数据,就返回一个列表。
        callback = key.data #accept
        callback(key.fileobj, mask) #key.fileobj:文件句柄

 客户端:

import socket

s=socket.socket()
s.connect(('localhost',9998))
while True:
    msg=bytes(input(">>:"),encoding='utf8')
    s.send(msg)
    data=s.recv(1024)
    print("recv:",data)
s.close()

 运行结果:

多连接可以并发。

多个用户接入:

#_*_coding:utf-8_*_
__author__ = 'Alex Li'


import socket
import sys

messages = [ b'This is the message. ',
             b'It will be sent ',
             b'in parts.',
             ]
server_address = ('localhost', 9998)

# Create a TCP/IP socket
socks = [ socket.socket(socket.AF_INET, socket.SOCK_STREAM),
          socket.socket(socket.AF_INET, socket.SOCK_STREAM),
          socket.socket(socket.AF_INET, socket.SOCK_STREAM),
          socket.socket(socket.AF_INET, socket.SOCK_STREAM),
          socket.socket(socket.AF_INET, socket.SOCK_STREAM),
          ]

# Connect the socket to the port where the server is listening
print('connecting to %s port %s' % server_address)
for s in socks:
    s.connect(server_address)

for message in messages:

    # Send messages on both sockets
    for s in socks:
        print('%s: sending "%s"' % (s.getsockname(), message) )
        s.send(message)

    # Read responses on both sockets
    for s in socks:
        data = s.recv(1024)
        print( '%s: received "%s"' % (s.getsockname(), data) )
        if not data:
            print('closing socket', s.getsockname() )
原文地址:https://www.cnblogs.com/momo8238/p/7389600.html