【问题标题】:If socket timeout set small value, does it have any disadvantage or bug?如果套接字超时设置较小的值,它有什么缺点或错误吗?
【发布时间】:2018-04-05 01:25:48
【问题描述】:

当我使用 python 进行套接字编程时,
我注意到一些操作并没有因中断而停止。例如:accept()recv()
所以我使用小超时来解决这个问题,即每 1 秒,程序停止操作并重新调用。例如,

socket.settimeout(1)    
while True:
    try:
        socket.recv()
    except timeout:
        # back to socket.recv()
        continue
    except KeyboardInterrupt:
        break

是否存在一些潜在问题,例如在超时异常期间丢失某些消息或操作系统负载过重等?

而且,您有什么更好的办法来停止不使用超时的套接字吗?请告诉我,我很感激你的回答。

还有一件事需要考虑。我在 Windows 中测试了这个程序,并且即使我按下 ctrl+C,在 recv() 完成后 KeyboardInterrupt 实际上也会引发。但是在 MacOS 或 Linux 中,KeyboardInterrupt 会在按下 ctrl+C 后引发。 Windows 和 Linux/Unix 有区别吗?

【问题讨论】:

    标签: python sockets timeout


    【解决方案1】:

    对于套接字,丢失数据的风险取决于套接字类型。

    对于SOCK_DGRAM 套接字,不能保证协议是可靠的。这意味着一般来说,无论您如何编程recv() 调用,您都应该预料到一些消息将会丢失。

    使用SOCK_STREAM,可以保证传入的数据流是可靠的,并且按照发送的顺序。

    如果您调用socket.settimeout(0)socket.setblocking(False),则recv() 检查套接字的接收缓冲区是否有传入数据,如果没有,则fails with an error that depends on the operating system。这可以用于定期轮询数据,同时还可以做其他事情。但是,它也可以将特定于操作系统的行为引入您的程序。

    另一种常用技术是创建一个线程,其唯一目的是发送和接收设置为阻塞模式的套接字 [socket.setblocking(True)]。在这种情况下,线程可以调用recv() 并在必要时等待直到数据实际进入。此设置允许您将协议编程为send()recv() 调用之间的对话。

    对于同时处理来自多个套接字的消息的应用程序,select() 可用于确定一组中的哪些套接字具有到 recv() 的待处理数据。需要注意的一点是select() 在需要高性能的情况下可能效率低下。

    【讨论】:

    • 超时值为零意味着无穷大,而不是零。它不是轮询套接字的机制。
    • @EJP 根据socket.settimeout() 的文档,0 将套接字置于非阻塞模式,而 None 将其置于阻塞模式(无限超时)。
    猜你喜欢
    • 2012-12-16
    • 2016-07-10
    • 1970-01-01
    • 2012-04-20
    • 2012-11-12
    • 1970-01-01
    • 1970-01-01
    • 2021-08-22
    相关资源
    最近更新 更多