Python中accept()方法与select()方法的结合应用
发布时间:2023-12-23 02:52:47
在Python中,accept()方法用于接受客户端的连接请求,select()方法用于多路复用地监测socket是否有数据可读。
下面是一个使用accept()方法和select()方法结合的示例,实现一个简单的多人聊天室:
import select
import socket
import sys
# 创建一个服务器socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('localhost', 1234))
server_socket.listen(10)
# 使用select方法进行IO多路复用
inputs = [server_socket]
outputs = []
message_queues = {}
while True:
# 使用select方法监测socket是否有数据可读
readable, writable, exceptional = select.select(inputs, outputs, inputs)
for s in readable:
if s is server_socket:
# 有新的连接请求
client_socket, client_address = s.accept()
inputs.append(client_socket)
message_queues[client_socket] = []
print("新连接: %s" % client_address)
else:
# 有数据可读
data = s.recv(1024)
if data:
# 将数据保存到该连接的消息队列
message_queues[s].append(data)
if s not in outputs:
outputs.append(s)
else:
# 客户端关闭连接
if s in outputs:
outputs.remove(s)
inputs.remove(s)
s.close()
del message_queues[s]
for s in writable:
# 有数据可写
if len(message_queues[s]) == 0:
outputs.remove(s)
else:
data = message_queues[s].pop(0)
s.send(data)
for s in exceptional:
# 异常情况
inputs.remove(s)
if s in outputs:
outputs.remove(s)
s.close()
del message_queues[s]
该示例中,首先创建一个服务器socket,并使用select方法对其进行监听。然后创建了三个列表inputs、outputs和message_queues,分别用于存储可读的socket、可写的socket和每个socket对应的消息队列。
进入主循环后,使用select方法进行IO多路复用,获取可读、可写和异常的socket列表。然后遍历可读的socket列表,如果是服务器socket,则表示有新的连接请求,接受连接,并将新连接的socket加入到inputs列表和message_queues字典中。如果是已经连接的客户端socket,则表示有数据可读,将数据保存到对应的消息队列中。
然后遍历可写的socket列表,如果消息队列不为空,则将队列中的数据发送出去。
最后遍历异常的socket列表,将异常的socket从inputs和outputs列表中移除,并关闭socket连接。
通过以上的例子,我们可以看到accept()方法和select()方法的结合能够实现一个基本的多人聊天室功能,同时解决了多个连接读写的问题。
