如何设置python套接字recv方法的超时?

2025-02-27 09:06:00
admin
原创
69
摘要:问题描述:我需要在 python 的套接字 recv 方法上设置超时。该怎么做?解决方案 1:典型的方法是使用select()等待,直到数据可用或超时。只有recv()当数据实际可用时才调用。为了安全起见,我们还将套接字设置为非阻塞模式,以保证recv()永远不会无限期阻塞。 select()也可用于一次等待...

问题描述:

我需要在 python 的套接字 recv 方法上设置超时。该怎么做?


解决方案 1:

典型的方法是使用select()等待,直到数据可用或超时。只有recv()当数据实际可用时才调用。为了安全起见,我们还将套接字设置为非阻塞模式,以保证recv()永远不会无限期阻塞。 select()也可用于一次等待多个套接字。

import select

mysocket.setblocking(0)

ready = select.select([mysocket], [], [], timeout_in_seconds)
if ready[0]:
    data = mysocket.recv(4096)

如果您有很多打开的文件描述符,poll()是一个更有效的替代方案select()

另一个选择是使用为套接字上的所有操作设置超时socket.settimeout(),但我发现您已在另一个答案中明确拒绝了该解决方案。

解决方案 2:

socket.settimeout()

解决方案 3:

如上所述,两者都select.select()可以socket.settimeout()起作用。

请注意,你可能需要settimeout根据自己的需要拨打两次电话,例如

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("",0))
sock.listen(1)
# accept can throw socket.timeout
sock.settimeout(5.0)
conn, addr = sock.accept()

# recv can throw socket.timeout
conn.settimeout(5.0)
conn.recv(1024)

解决方案 4:

您可以在收到响应之前设置超时,并在收到响应后将其设置回无:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sock.settimeout(5.0)
data = sock.recv(1024)
sock.settimeout(None)

解决方案 5:

如果您实现服务器端,则您正在寻找的超时是连接套接字的超时,而不是主套接字的超时。换句话说,连接套接字对象还有另一个超时,这是socket.accept()方法的输出。因此:

sock.listen(1)
connection, client_address = sock.accept()
connection.settimeout(5)    # This is the one that affects recv() method.
connection.gettimeout()     # This should result 5
sock.gettimeout()           # This outputs None when not set previously, if I remember correctly.

如果您实现客户端,那就简单了。

sock.connect(server_address)
sock.settimeout(3)

解决方案 6:

我对上面的答案有点困惑,所以我写了一个小要点并附带例子以便更好地理解。


选项 #1 -socket.settimeout()

sock.recv()如果等待时间超过定义的超时时间,将会引发异常。

import socket

sock = socket.create_connection(('neverssl.com', 80))
timeout_seconds = 2
sock.settimeout(timeout_seconds)
sock.send(b'GET / HTTP/1.1
Host: neverssl.com

')
data = sock.recv(4096)
data = sock.recv(4096) # <- will raise a socket.timeout exception here

选项 #2 -select.select()

等待数据发送,直到超时。我修改了Daniel 的答案,因此它会引发异常

import select
import socket

def recv_timeout(sock, bytes_to_read, timeout_seconds):
    sock.setblocking(0)
    ready = select.select([sock], [], [], timeout_seconds)
    if ready[0]:
        return sock.recv(bytes_to_read)

    raise socket.timeout()

sock = socket.create_connection(('neverssl.com', 80))
timeout_seconds = 2
sock.send(b'GET / HTTP/1.1
Host: neverssl.com

')
data = recv_timeout(sock, 4096, timeout_seconds)
data = recv_timeout(sock, 4096, timeout_seconds) # <- will raise a socket.timeout exception here

解决方案 7:

您可以使用socket.settimeout()它来接受表示秒数的整数参数。例如,socket.settimeout(1)将超时设置为 1 秒

解决方案 8:

尝试一下它使用底层 C。

timeval = struct.pack('ll', 2, 100)
s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, timeval)

解决方案 9:

#! /usr/bin/python3.6

# -*- coding: utf-8 -*-
import socket
import time
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.settimeout(5)
PORT = 10801

s.bind(('', PORT))
print('Listening for broadcast at ', s.getsockname())
BUFFER_SIZE = 4096
while True:
    try:
        data, address = s.recvfrom(BUFFER_SIZE)
    except socket.timeout:
        print("Didn't receive data! [Timeout 5s]")
        continue

解决方案 10:

正如前面的回复中提到的,您可以使用类似以下内容:.settimeout()
例如:

import socket

s = socket.socket()

s.settimeout(1) # Sets the socket to timeout after 1 second of no activity

host, port = "somehost", 4444
s.connect((host, port))

s.send("Hello World!
")

try:
    rec = s.recv(100) # try to receive 100 bytes
except socket.timeout: # fail after 1 second of no activity
    print("Didn't receive data! [Timeout]")
finally:
    s.close()

我希望这有帮助!

解决方案 11:

致谢:https://boltons.readthedocs.io/en/latest/socketutils.html

它提供了一个缓冲套接字,这提供了很多非常有用的功能,例如:

.recv_until()    #recv until occurrence of bytes
.recv_closed()   #recv until close
.peek()          #peek at buffer but don't pop values
.settimeout()    #configure timeout (including recv timeout)
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3018  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1880  
  PLM(产品生命周期管理)系统在企业产品研发、生产与管理过程中发挥着至关重要的作用。它能够整合产品全生命周期中的各类数据与流程,提升企业的协同效率、降低成本并加速产品上市。然而,不同企业由于业务模式、产品特性以及管理理念的差异,对PLM系统有着个性化的需求。如何实现这些个性化需求,成为企业在实施PLM系统定制开发时面临...
免费plm软件   0  
  在企业的发展进程中,跨地域协同工作变得愈发普遍和重要。不同地区的团队需要紧密合作,以实现资源共享、提高效率和创新能力。而产品生命周期管理(PLM)系统在这一过程中发挥着关键作用,尤其是其分布式架构,为跨地域协同提供了强大的支持。PLM系统概述PLM系统是一种用于管理产品从概念设计到退役全生命周期过程中所有数据和流程的软...
免费plm管理软件   0  
  在企业项目管理中,资源平衡是确保项目顺利推进、提高效率与效益的关键环节。产品生命周期管理(PLM)系统作为整合产品全生命周期信息与流程的重要工具,为实现资源平衡提供了强大的支持。通过合理运用PLM系统,企业能够优化资源分配、提升协同效率,从而在激烈的市场竞争中占据优势。接下来,我们将深入探讨如何借助PLM系统实现资源平...
plm系统   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用