利用selectors模块实现Python中的TCP/IP通信
发布时间:2023-12-24 04:22:27
Python中的selectors模块是一个高级的I/O多路复用库,它可以有效地处理多个socket通信。在TCP/IP通信中,使用selectors模块可以实现同时处理多个客户端的连接请求和数据传输。下面是一个使用selectors模块实现TCP/IP通信的例子:
import selectors
import socket
# 创建一个selectors对象
sel = selectors.DefaultSelector()
# 定义服务器地址和端口
HOST = 'localhost'
PORT = 8080
# 创建服务器socket并绑定地址和端口
server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_sock.bind((HOST, PORT))
server_sock.listen()
print("服务器启动,监听地址为{},端口为{}".format(HOST, PORT))
# 设置为非阻塞模式
server_sock.setblocking(False)
# 注册服务器socket,监听事件为读事件
sel.register(server_sock, selectors.EVENT_READ, data=None)
# 处理连接请求和数据传输
def accept(sock):
conn, addr = sock.accept()
print("客户端{}已连接".format(addr))
# 设置为非阻塞模式
conn.setblocking(False)
# 创建客户端socket
data = types.SimpleNamespace(addr=addr, inb=b'', outb=b'')
events = selectors.EVENT_READ | selectors.EVENT_WRITE
sel.register(conn, events, data=data)
def recv(sock, data):
recv_data = sock.recv(1024)
if recv_data:
data.outb += recv_data
else:
addr = data.addr
print("客户端{}已断开连接".format(addr))
sel.unregister(sock)
sock.close()
def send(sock, data):
if data.outb:
send_data = data.outb
data.outb = b''
sock.sendall(send_data)
# 循环监听事件
while True:
# 获取所有已就绪的事件列表
events = sel.select()
# 处理每一个已就绪的事件
for key, mask in events:
sock = key.fileobj
data = key.data
# 如果是服务器socket,则调用accept函数处理连接请求
if sock == server_sock:
accept(sock)
# 如果是客户端socket且有读事件,则调用recv函数接收数据
elif mask & selectors.EVENT_READ:
recv(sock, data)
# 如果是客户端socket且有写事件,则调用send函数发送数据
elif mask & selectors.EVENT_WRITE:
send(sock, data)
在这个例子中,我们使用默认的selectors对象 selectors.DefaultSelector() ,创建服务器socket并绑定地址和端口,然后将服务器socket注册到selectors对象中,监听读事件。当有客户端连接请求时,调用accept函数处理连接请求,并创建客户端socket并注册到selectors对象中,监听读和写事件。当客户端有数据到达时,调用recv函数接收数据,并将准备发送的数据添加到outb中。当客户端socket可写时,调用send函数发送数据。
通过上面的例子,我们可以实现一个简单的TCP/IP通信程序,并同时处理多个客户端的连接请求和数据传输。selectors模块提供了很多功能丰富的API,可用于更高级的I/O多路复用操作。
