如何使socket.recv(500)不停止while循环

时间:2010-03-14 19:13:19

标签: python sockets while-loop

我制作了一个IRC机器人,它使用了一个真正的循环来接收所说的内容 要接收我使用recv(500),但如果没有任何东西可以接收,那就会停止循环,但即使没有任何东西可以接收,我也需要循环继续。
我需要一个临时计时器继续运行。

示例代码:

/A lot of stuff/
timer=0
while 1:
    timer=timer+1
    line=s.recv(500) #If there is nothing to receive, the loop and thus the timer stop.
/A lot of stuff/

所以要么我需要一种方法来阻止它停止循环,要么我需要一个更好的计时器。

4 个答案:

答案 0 :(得分:2)

您可以在套接字上settimeout以便呼叫迅速返回(使用合适的exception,因此您需要尝试/除了它之外)如果没有任何内容 - 超时为0.1在大多数情况下,秒实际上比非阻塞套接字更好。

答案 1 :(得分:1)

这将成为设计网络应用程序的一种不好的方法。我建议查看twisted,这是一个网络库,具有出色的IRC协议实现,可以在twisted.words.protocols.irc中创建客户端(如机器人)。

http://www.habnabit.org/twistedex.html是使用twisted编写的非常基本的IRC bot的示例。只需很少的代码,您就可以访问IRC的完整,正确,高效,重新连接的实现。

如果您打算自己从套接字级别编写此文件,我仍然建议您学习像twisted这样的网络库,以了解如何有效地实现网络应用程序。你目前的技术证明效果不如预期。

答案 2 :(得分:1)

我通常使用irclib来处理这类细节。

答案 3 :(得分:1)

如果你想用低级python执行此操作,请考虑使用ready_sockets = select.select([s.fileno()], [], [], 0.1) - 这将测试套接字s的可读性。如果未在ready_sockets中返回套接字的文件编号,则无法读取数据。

如果要在一个不会产生CPU的循环中重复调用select,请注意不要使用“0”的timout - 这会在循环执行时消耗100%的CPU。我举了0.1秒超时作为例子;在这种情况下,你的计时器变量将计算十分之一秒。

以下是一个例子:

timer=0    
sockets_to_check = [s.fileno()]

while 1:
    ready_sockets = select.select(sockets_to_check, [], sockets_to_check, 0.1)
    if (len(ready_sockets[2]) > 0):
        # Handle socket error or closed connection here -- our socket appeared
        # in the 'exceptional sockets' return value so something has happened to 
        # it.
    elif (len(ready_sockets[0]) > 0):
        line = s.recv(500)
    else:
        timer=timer+1  # Note that timer is not incremented if the select did not
                       # incur a full 0.1 second delay.  Although we may have just
                       # waited for 0.09999 seconds without accounting for that.  If
                       # your timer must be perfect, you will need to implement it
                       # differently.  If it is used only for time-out testing, this 
                       # is fine.

请注意,上面的代码利用了输入列表只包含一个套接字的事实。如果您使用这种方法(select.select支持多个套接字),则len(ready_sockets[x]) > 0测试不会显示哪个套接字已准备好进行读取或有异常。