【问题标题】:How to prevent a program from waiting to receive a message from client?如何防止程序等待接收来自客户端的消息?
【发布时间】:2019-06-19 19:37:30
【问题描述】:

我正在创建一个聊天系统,程序将尝试从每个在线客户端接收消息,但问题是程序正在等待第一个客户端发送和接收内容,然后它正在监听另一个客户端。 请看下面的代码我简化了代码没有提供main。

import socket
port = input("Port: ")
s = socket.socket()
s.bind(('', port))
s.listen(5)
a, b = s.accept()
print "Connection", "with", b[0], "Created Successfully"
while True:
    try:
        rec = a.recv(1024)
        print rec
    except:
        print "Time Out"

我希望程序检查rec 中是否有任何值(客户端程序是否发送了任何内容),如果没有,它将打印Time Out 而无需等待客户端发送任何内容。

【问题讨论】:

  • 你想使用poll(2)系统调用。
  • 您当前正在做的称为阻塞调用来接收字节,您要做的是非阻塞调用来接收数据(并传递回调以进行更新),以便您的主线程不会冻结。

标签: python python-2.7 sockets networking


【解决方案1】:

访问https://docs.python.org/2/library/socket.html#socket-objects 这是针对socket python2.7的

socket.setblocking(标志) 设置套接字的阻塞或非阻塞模式:如果标志为0,则套接字设置为非阻塞,否则为阻塞模式。最初所有套接字都处于阻塞模式。在非阻塞模式下,如果 recv() 调用没有找到任何数据,或者如果 send() 调用不能立即处理数据,则会引发错误异常;在阻塞模式下,调用会阻塞,直到它们可以继续。 s.setblocking(0) 等价于 s.settimeout(0.0); s.setblocking(1) 等价于 s.settimeout(None)。

socket.settimeout(值) 设置阻塞套接字操作的超时。 value 参数可以是表示秒数的非负浮点数,也可以是 None。如果给定一个浮点数,如果在操作完成之前超时时间值已经过去,则后续套接字操作将引发超时异常。将超时设置为 None 会禁用套接字操作的超时。 s.settimeout(0.0) 等价于 s.setblocking(0); s.settimeout(None) 等价于 s.setblocking(1)。

【讨论】:

    【解决方案2】:

    多线程编程:你需要一个线程来运行你的监听函数。

    【讨论】:

      【解决方案3】:

      Python 中有许多选项。仅举两个例子,https://twistedmatrix.com/https://docs.python.org/3/library/asyncio.html

      【讨论】:

        【解决方案4】:

        您的问题是特定于操作系统的。

        使用select & poll - Waiting for I/O completion 操作。可能还有selectors 模块。或者找一些event loop 模块。

        您可能想阅读ALP 以了解如何使用Linux system calls(列于syscalls(2);阅读有关poll(2)

        您可以阅读Operating System: Three Easy Pieces 以了解有关操作系统的更多信息。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-12-15
          • 2015-03-22
          • 1970-01-01
          • 1970-01-01
          • 2018-09-02
          • 2013-03-28
          • 1970-01-01
          相关资源
          最近更新 更多