Python:检查 IRC 连接是否丢失(PING PONG?)
所以我的问题是,如果有 PING,我如何让我的机器人监听,如果在一分钟的时间间隔内没有 ping,它会做出反应,就好像连接已丢失一样。一个人会怎样做呢?
编辑:
这是注册连接失败的工作代码(尽管重新连接时遇到问题):
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import socket
import string
import os
import platform
import time
# Variables
HOST = "irc.channel.net"
PORT = 6667
NICK = "Botname"
IDENT = "Botname"
REALNAME = os.getenv('USER')
CHAN = "##ChannelName"
readbuffer = ""
# Our IRC connection
irc = socket.socket()
irc.settimeout(300)
connected = False
def connection(host, port, nick, ident, realname, chan):
while connected is False:
try:
irc.connect((host, port))
irc.send("NICK %s\r\n" % nick)
irc.send("USER %s %s bla :%s\r\n" % (ident, host, realname))
irc.send("JOIN :%s\r\n" % chan)
# Initial msg to send when bot connects
irc.send("PRIVMSG %s :%s\r\n" % (chan, "TehBot: "+ nick + " Realname: " + realname + " ."))
global connected
connected = True
except socket.error:
print "Attempting to connect..."
time.sleep(5)
continue
connection(HOST, PORT, NICK, IDENT, REALNAME, CHAN)
while connected:
try:
data = irc.recv ( 4096 )
# If connection is lost
if len(data) == 0:
break
print data
# If Nick is in use
if data.find ( "Nickname is already in use" ) != -1:
NICK = NICK + str(time.time())
connection(HOST, PORT, NICK, IDENT, REALNAME, CHAN)
# Ping Pong so we don't get disconnected
if data[0:4] == "PING":
irc.send ( "PONG " + data.split() [ 1 ] + "\r\n" )
except socket.timeout:
global connected
connected = False
print connected
break
print "Out of loop"
connection(HOST, PORT, NICK, IDENT, REALNAME, CHAN)
So my question is, how would i get my bot to listen if there is a PING and if there's no ping in an interval of a minute, it will react as though the connection has been lost. How would one go about doing that?
EDIT:
This is the working code for registering the connection fallout (although having trouble with reconnecting):
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import socket
import string
import os
import platform
import time
# Variables
HOST = "irc.channel.net"
PORT = 6667
NICK = "Botname"
IDENT = "Botname"
REALNAME = os.getenv('USER')
CHAN = "##ChannelName"
readbuffer = ""
# Our IRC connection
irc = socket.socket()
irc.settimeout(300)
connected = False
def connection(host, port, nick, ident, realname, chan):
while connected is False:
try:
irc.connect((host, port))
irc.send("NICK %s\r\n" % nick)
irc.send("USER %s %s bla :%s\r\n" % (ident, host, realname))
irc.send("JOIN :%s\r\n" % chan)
# Initial msg to send when bot connects
irc.send("PRIVMSG %s :%s\r\n" % (chan, "TehBot: "+ nick + " Realname: " + realname + " ."))
global connected
connected = True
except socket.error:
print "Attempting to connect..."
time.sleep(5)
continue
connection(HOST, PORT, NICK, IDENT, REALNAME, CHAN)
while connected:
try:
data = irc.recv ( 4096 )
# If connection is lost
if len(data) == 0:
break
print data
# If Nick is in use
if data.find ( "Nickname is already in use" ) != -1:
NICK = NICK + str(time.time())
connection(HOST, PORT, NICK, IDENT, REALNAME, CHAN)
# Ping Pong so we don't get disconnected
if data[0:4] == "PING":
irc.send ( "PONG " + data.split() [ 1 ] + "\r\n" )
except socket.timeout:
global connected
connected = False
print connected
break
print "Out of loop"
connection(HOST, PORT, NICK, IDENT, REALNAME, CHAN)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这将记录每次获得 ping 的时间,如果没有 ping 的时间太长,则跳出
connected
循环。您不需要whileconnected==True:
,只需whileconnected:
做同样的事情。另外,请考虑使用
connection
而不是Connection
,Python 约定仅对类使用大写名称。This will record the time each time it gets a ping, and if it goes too long without one, break out of the
connected
loop. You don't needwhile connected == True:
, justwhile connected:
does the same thing.Also, consider using
connection
instead ofConnection
, it's the Python convention to use capitalized names only for classes.只要您的连接仍然有效,就没有理由执行任何花哨的“超时”技巧。如果
recv
返回的数据长度为0,则TCP连接已关闭。我怀疑如果连接没有完全终止,recv() 也会抛出异常。
编辑:
我不确定您想要实现什么目标。 IRC 服务器偶尔会向您发送
PING
。如果您不响应PONG
,服务器将断开您的连接。当服务器断开连接时,您的recv()
调用将返回一个 0 长度的字符串。您所要做的就是在收到
PING
时做出响应,并在连接碰巧关闭时进行处理。您的逻辑应该如下所示:
另一件要记住的事情是,您需要缓冲任何接收到的数据,直到获得
\r\n
序列,您不会总是获得一个完整的消息同时;你可能会得到一行的一半,或者三行,或者三行半。There's no reason to do any fancy 'timeout' tricks as long as your connection is still up. If the length of the data returned from
recv
is 0, the TCP connection has been closed.I suspect that recv() can also throw an exception if the connection is not terminated cleanly.
Edit:
I'm not sure what you're trying to accomplish. The IRC server will send you a
PING
occasionally. If you don't respond with aPONG
, then the server will disconnect you. When the server disconnects you, then yourrecv()
call will return a 0-length string.All you have to do is respond to
PING
when you get it, and handle if the connection happens to close.Your logic should look something like this:
Another thing to keep in mind is that you need to buffer any received data until you get a
\r\n
sequence, you will not always get a exactly one complete message at the same time; you might get half of one, or three, or three and a half lines.您不应使用
data.find('PING')
,因为它还会在其他消息中查找“PING”。然后你发送了一个不正确的 PONG...而是尝试这样的事情:
You should not use
data.find('PING')
because it also finds "PING" in other messages. And then you send an incorrect PONG...Instead try something like that:
重新连接时遇到问题的原因是,一旦重新连接,就没有循环可侦听传入数据,并且很可能会出现 ping 超时。连接 while 循环应如下所示:
现在,当连接超时时,您将重新连接并开始侦听传入数据。
注意:现在应用程序无法终止,您必须在命令行中按 [Ctrl]+[C],或者构造一个“!quit”类型命令来关闭套接字和应用程序...当然,首先是套接字。
The reason why your having issues reconnecting is because once you do there's no loop to listen to for incoming data once you do, and you'd most likely ping timeout. The connection while loop should look like:
Now when the connection times out you reconnect and begin to listen for incoming data.
NOTE: Now that there's no way for the application to terminate on it's on you have to either [Ctrl]+[C] in the command line, or construct a "!quit" type command to close the socket and the application... socket first, of course.