要解决在每个循环迭代中等待 socket.accept()
的问题,可以使用非阻塞的套接字(non-blocking socket)和 select
或 poll
函数来实现异步的套接字监听。以下是一个使用 select
函数的代码示例:
import select
import socket
# 创建套接字并设置为非阻塞模式
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setblocking(0)
# 绑定地址并开始监听
server_socket.bind(('localhost', 8000))
server_socket.listen(5)
# 创建一个列表来存储要监听的套接字
sockets_list = [server_socket]
while True:
# 使用 select 函数来监听套接字的状态变化
readable, writable, exceptional = select.select(sockets_list, [], [])
for sock in readable:
if sock is server_socket:
# 如果是服务器套接字,表示有新的连接请求
client_socket, client_address = server_socket.accept()
client_socket.setblocking(0)
sockets_list.append(client_socket)
print(f"Accepted new connection from {client_address}")
else:
# 如果是客户端套接字,表示有数据可读
data = sock.recv(1024)
if data:
print(f"Received data: {data.decode()}")
else:
# 如果没有数据,表示连接已关闭,移除套接字
sock.close()
sockets_list.remove(sock)
print("Client connection closed")
在上述代码中,select
函数会阻塞,直到至少一个套接字准备好进行读取操作。这样,我们就不需要在每个循环迭代中等待 socket.accept()
,而是通过 select
函数来等待连接请求。同时,我们还可以在同一个循环中处理多个客户端连接。