使用Python的Selector()进行TCP/UDP套接字编程的示例
发布时间:2023-12-27 11:19:19
在Python中,可以使用selectors模块的Selector类来进行TCP和UDP套接字编程。Selector是一个异步I/O框架,它可以同时监视多个套接字,并在就绪时进行相应的操作。
下面是一个使用Selector进行TCP套接字编程的示例:
import selectors
import socket
# 创建一个Selector对象
selector = selectors.DefaultSelector()
# 创建一个TCP服务器套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 8000))
server_socket.listen(10)
# 设置套接字为非阻塞模式
server_socket.setblocking(False)
# 注册套接字到Selector对象,监视可读事件
selector.register(server_socket, selectors.EVENT_READ)
def accept_connection(sock):
# 接受客户端连接
client_socket, addr = sock.accept()
print("Accepted connection from", addr)
# 设置客户端套接字为非阻塞模式
client_socket.setblocking(False)
# 注册客户端套接字到Selector对象,监视可读事件
selector.register(client_socket, selectors.EVENT_READ)
def handle_request(sock):
# 接收客户端请求数据
data = sock.recv(1024)
if data:
# 处理请求并返回响应数据
response = b'Hello, World!
'
sock.send(response)
else:
# 关闭连接并取消在Selector对象中的监视
print('Closing connection')
selector.unregister(sock)
sock.close()
def event_loop():
while True:
# 等待就绪事件
events = selector.select()
for key, mask in events:
if key.data is None:
# 如果事件是来自服务器套接字的可读事件,表示有新的客户端连接
accept_connection(key.fileobj)
else:
# 其他情况为客户端套接字的可读事件,表示有客户端发送请求
handle_request(key.fileobj)
if __name__ == '__main__':
event_loop()
此示例创建了一个TCP服务器套接字,并使用Selector对象来监听可读事件。在事件循环中,首先等待就绪事件,如果事件来自服务器套接字的可读事件,表示有新的客户端连接,就接受连接并注册客户端套接字到Selector对象。如果事件是客户端套接字的可读事件,表示有客户端发送请求,就接收请求数据并进行处理。最后,如果请求数据为空,表示客户端关闭连接,就关闭连接并取消在Selector对象中的监视。
下面是一个使用Selector进行UDP套接字编程的示例:
import selectors
import socket
# 创建一个Selector对象
selector = selectors.DefaultSelector()
# 创建一个UDP套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_socket.bind(('localhost', 8000))
# 设置套接字为非阻塞模式
udp_socket.setblocking(False)
# 注册套接字到Selector对象,监视可读事件
selector.register(udp_socket, selectors.EVENT_READ)
def handle_request(sock, addr):
# 接收客户端请求数据
data, addr = sock.recvfrom(1024)
if data:
# 处理请求并返回响应数据
response = b'Hello, World!
'
sock.sendto(response, addr)
def event_loop():
while True:
# 等待就绪事件
events = selector.select()
for key, mask in events:
# 获取套接字和地址
sock = key.fileobj
addr = None
if sock == udp_socket:
# 如果事件来自UDP套接字的可读事件,表示有客户端发送请求
handle_request(sock, addr)
if __name__ == '__main__':
event_loop()
此示例创建了一个UDP套接字,并使用Selector对象来监听可读事件。在事件循环中,首先等待就绪事件,如果事件来自UDP套接字的可读事件,表示有客户端发送请求,就接收请求数据并进行处理。最后,将响应数据发送给客户端。
