select模块

Python标准库中的select模块,这个模块提供了select函数,它能够监视文件描述符,等待它们变得“就绪”(即可读、可写或发生异常)。这在处理I/O、网络通信或异步操作时非常有用。

select模块的基本使用

导入模块
import select
监听文件描述符
# 创建文件描述符列表
read_fds, write_fds, err_fds = select.select(inputs, outputs, exceptions, timeout)
  • inputs: 等待读就绪的文件描述符列表。
  • outputs: 等待写就绪的文件描述符列表。
  • exceptions: 等待异常的文件描述符列表。
  • timeout: 超时时间。
示例
import select
import socket
# 创建socket对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('0.0.0.0', 8080))
server_socket.listen()
# 设置为非阻塞模式
server_socket.setblocking(0)
# 准备好读取的列表
inputs = [server_socket]
while True:
    # 使用select监听
    readable, writable, exceptional = select.select(inputs, [], [])
    for s in readable:
        if s is server_socket:
            # 处理新的连接
            connection, client_address = s.accept()
            print("新连接来自", client_address)
            connection.setblocking(0)
            inputs.append(connection)
        else:
            # 处理客户端数据
            data = s.recv(1024)
            if data:
                print("收到数据:", data)
            else:
                # 没有数据表示客户端断开
                print("关闭连接")
                inputs.remove(s)
                s.close()

这个示例创建了一个简单的TCP服务器,它使用select来同时处理多个连接。

Python 的 socket 模块通过使用 selectpoll 系统调用来实现超时判断。这些系统调用允许程序在等待某个文件描述符(例如,socket)的状态变化时指定一个超时值。如果在指定的超时值内没有发生状态变化,系统调用将返回并触发超时异常。以下是这两个系统调用的工作原理和实现方式:

select 系统调用

select 系统调用允许程序监视多个文件描述符,等待它们变为可读、可写或发生异常。select 接受三个文件描述符集和一个超时值作为参数,并在文件描述符状态发生变化或超时后返回。

poll 系统调用

poll 系统调用与 select 类似,但更灵活和高效。它使用一个包含文件描述符及其感兴趣事件的数组,而不是三个独立的文件描述符集。poll 也支持更大的文件描述符数量。

实现原理

在 Python 中,socket 模块通过 _socket 模块和 selectors 模块来使用这些系统调用。以下是一个简化的示例,展示了如何使用 select 来实现超时:

import socket
import select

# 创建一个 socket 对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 设置非阻塞模式
s.setblocking(0)

# 设置超时(以秒为单位)
timeout = 5

# 连接到服务器(注意:此处会立即返回,因为 socket 是非阻塞的)
server_address = ('example.com', 80)
s.connect_ex(server_address)

# 使用 select 监视 socket 的可写性(表示连接已建立)
ready = select.select([], [s], [], timeout)

if ready[1]:
    print("Connection established")
else:
    print("Connection timed out")

# 发送一个请求
request = b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"
s.sendall(request)

# 使用 select 监视 socket 的可读性(表示有响应数据可读)
ready = select.select([s], [], [], timeout)

if ready[0]:
    response = s.recv(4096)
    print("Response received")
    print(response.decode('utf-8'))
else:
    print("Receiving response timed out")

# 关闭 socket
s.close()

在这个示例中:

  1. 创建和配置 socket

    • 创建一个 TCP socket,并将其设置为非阻塞模式,以便 connect_ex 调用不会阻塞程序执行。
  2. 连接到服务器

    • 使用 connect_ex 方法发起连接请求。由于 socket 是非阻塞的,这个调用会立即返回。
  3. 使用 select 监视连接状态

    • 使用 select 函数监视 socket 的可写性(表示连接已建立)。如果在指定的超时时间内 socket 变为可写,连接成功;否则,连接超时。
  4. 发送请求和接收响应

    • 发送请求数据后,再次使用 select 监视 socket 的可读性(表示有数据可读)。如果在指定的超时时间内 socket 变为可读,读取响应数据;否则,接收超时。

通过这种方式,Python 的 socket 模块利用 selectpoll 系统调用实现了对网络操作的超时判断和处理。

相关推荐

  1. select模块

    2024-06-11 00:32:05       36 阅读
  2. 模型剪枝——SELECTIVE BRAIN DAMAGE

    2024-06-11 00:32:05       37 阅读
  3. TCP并发模型 || select || poll || epoll

    2024-06-11 00:32:05       40 阅读
  4. QT Model/View 设计模式selection 模型

    2024-06-11 00:32:05       64 阅读
  5. 多路IO复用服务器——select模型和poll模型

    2024-06-11 00:32:05       53 阅读
  6. C++Linux网络编程:简单的select模型运用

    2024-06-11 00:32:05       51 阅读
  7. Day 9. TCP并发模型select、poll、epoll

    2024-06-11 00:32:05       40 阅读
  8. 密码学系列2-安全模型(CPA,CCA,selective,adaptive)

    2024-06-11 00:32:05       32 阅读
  9. vue3中a-select模糊查询

    2024-06-11 00:32:05       36 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-11 00:32:05       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-11 00:32:05       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-11 00:32:05       87 阅读
  4. Python语言-面向对象

    2024-06-11 00:32:05       96 阅读

热门阅读

  1. js中如何清除一个对象中指定的键名

    2024-06-11 00:32:05       28 阅读
  2. 仓库管理业务在WMS与ERP中如何抉择

    2024-06-11 00:32:05       34 阅读
  3. 【数据结构】图之邻接矩阵代码实现与dfs、bfs

    2024-06-11 00:32:05       30 阅读
  4. 如何使用Python pottery库

    2024-06-11 00:32:05       32 阅读
  5. 动态规划算法

    2024-06-11 00:32:05       39 阅读
  6. 分享: 动图网站

    2024-06-11 00:32:05       33 阅读
  7. 本地部署 RAGFlow

    2024-06-11 00:32:05       37 阅读
  8. RGMII接口--->(013)FPGA实现RGMII接口(十三)

    2024-06-11 00:32:05       31 阅读
  9. 开机自启动脚本配置

    2024-06-11 00:32:05       31 阅读
  10. 本地化平台部署运维事项

    2024-06-11 00:32:05       34 阅读