MST

星途 面试题库

面试题:网络编程之非阻塞Socket超时处理基础

在非阻塞Socket编程中,描述一下如何实现简单的超时处理机制,假设使用Python语言,给出关键代码示例并解释原理。
22.7万 热度难度
后端开发网络编程

知识考点

AI 面试

面试题答案

一键面试

在非阻塞Socket编程中,可使用select模块来实现简单的超时处理机制。以下是关键代码示例及原理解释:

  1. 关键代码示例
import socket
import select

# 创建非阻塞socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setblocking(False)

try:
    sock.connect(('example.com', 80))
except BlockingIOError:
    pass

# 设置超时时间,单位为秒
timeout = 5
readable, writable, exceptional = select.select([], [sock], [], timeout)

if sock in writable:
    print('连接成功')
    sock.sendall(b'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n')
    readable, _, _ = select.select([sock], [], [], timeout)
    if sock in readable:
        data = sock.recv(1024)
        print('收到数据:', data.decode('utf-8'))
else:
    print('连接超时')

sock.close()
  1. 原理解释
    • select函数select模块提供了select函数,它允许程序监控多个文件描述符(在这个例子中是Socket对象),等待其中一个或多个变为可读、可写或发生异常。
    • 参数
      • 第一个参数是一个可读文件描述符的列表,这里为空[],因为我们先关注连接是否成功(可写状态)。
      • 第二个参数是一个可写文件描述符的列表,这里放入我们要连接的Socket对象sock
      • 第三个参数是一个异常文件描述符的列表,这里为空[]
      • 第四个参数timeout是超时时间,单位为秒。如果在这个时间内没有文件描述符变为指定状态,select函数将返回空的列表。
    • 连接超时处理:在尝试连接后,使用select函数等待Socket变为可写状态(意味着连接成功),如果在timeout时间内Socket变为可写,则连接成功;否则,select返回空列表,判定为连接超时。
    • 数据接收超时处理:连接成功后,向服务器发送数据,然后再次使用select函数等待Socket变为可读状态(意味着有数据可接收),同样设置timeout超时时间。如果在超时时间内Socket变为可读,则接收数据;否则,判定为数据接收超时。