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() )