我有一个python IRC机器人,我开始练习我的python。但是,对于某些服务器,它不会加入频道,尽管它已成功登录。我也希望它对像 !test 这样的用户命令做出反应,但我不确定该怎么做。在它工作的服务器上,它会成功 ping 回来。
from socket import socket, AF_INET, SOCK_STREAM
network = raw_input("Server: ")
port = 6667
chan = raw_input("Channel: ")
nick = raw_input("Nick: ")
irc=socket(AF_INET,SOCK_STREAM)
irc.connect((network, port))
a=irc.recv (4096)
print a
irc.send('NICK ' + nick + 'rn')
irc.send('USER john_bot john_bot bla :john_botrn')
irc.send('JOIN :' + chan + 'rn')
irc.send('PRIVMSG ' + chan + ' :Hello.rn')
def ircSend(msg):
print(msg)
irc.send(msg)
while True:
data = irc.recv(4096)
print data
if data.find('PING') != -1:
ircSend('PONG ' + data.split()[1] + 'rn')
在某些服务器上,您必须使用PONG响应PING,然后才能实际执行任何操作。
ircSend('NICK ' + nick + 'rn')
ircSend('USER john_bot john_bot bla :john_botrn')
data = ircRecv() # explained later
if data.find('PING') != -1:
ircSend('PONG ' + data.split()[1] + 'rn')
ircSend('JOIN :' + chan + 'rn')
ircSend('PRIVMSG ' + chan + ' :Hello.rn')
你真的不需要这个
a=irc.recv (4096)
print a
有时IRC服务器一次发送多行(例如MOTD或NAMES)。只要总字节数不超过 4096,这将很好地处理它(有些行会分成两行)
data = irc.recv(4096)
for line in data.split('rn'):
# process the line
如果一行会切成两半(很少会,就像 PING 碰巧在那里一样),我们可以一次接收一行并将其余字符留给套接字的缓冲区。但是,这可能效率较低(我没有测试过它,所以也许这根本不重要)
def ircRecv():
line = ''
while 1: # same as while True:
character = irc.recv(1)
if character == 'n':
break # exit the loop
elif character != 'r':
line += character
print line
return line
从 IRC RFC 的第 8 页:
<message> ::= [':' <prefix> <SPACE> ] <command> <params> <crlf>
<prefix> ::= <servername> | <nick> [ '!' <user> ] [ '@' <host> ]
<command> ::= <letter> { <letter> } | <number> <number> <number>
<SPACE> ::= ' ' { ' ' }
<params> ::= <SPACE> [ ':' <trailing> | <middle> <params> ]
<middle> ::= <Any *non-empty* sequence of octets not including SPACE
or NUL or CR or LF, the first of which may not be ':'>
<trailing> ::= <Any, possibly *empty*, sequence of octets not including
NUL or CR or LF>
<crlf> ::= CR LF
这意味着您始终可以轻松且肯定地获得消息的发件人,如下所示:
# put this inside the main loop
# this will throw an IndexError when the connection is closed,
# an empty line does not contain any spaces
line = ircRecv()
if line.split()[0].find('!') != -1:
# the first character must be a colon because <command> can't include
# an exclamation mark
someOneElsesNick = line[1:line.find('!')]
command = line.split()[1]
有人打招呼时回答!
if command == 'PRIVMSG':
destination = line.split()[2] # channel or bot's nick
# <trailing>, in this case, the message
message = line[line[1:].find(':')+2 : ] # everything after the 2nd colon
# we add one since we don't want include the <trailing> colon in
# the message and an other one because line[1:].find() is one smaller
# number than line.find() would be
# if we receive a private message, we have to respond to the sender,
# not to ourself
if destination == nick:
destination = someOneElsesNick
if message.startswith('hi!'):
ircSend('PRIVMSG ' + destination + ' :Hi, '
+ someOneElsesNick + '!rn')
有关更多信息,请查看 IRC RFC: http://www.ietf.org/rfc/rfc1459.txt(尤其是第 2.3.1 和 4 节)。如果您不想处理 IRC 协议,请使用扭曲:)http://twistedmatrix.com/trac/