我制作了一个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/
所以要么我需要一种方法来阻止它停止循环,要么我需要一个更好的计时器。
答案 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
测试不会显示哪个套接字已准备好进行读取或有异常。