欢迎访问宙启技术站
智能推送

使用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套接字的可读事件,表示有客户端发送请求,就接收请求数据并进行处理。最后,将响应数据发送给客户端。