英文:
Simple golang IRC bot keeps timing out
问题
我正在使用golang进行尝试,并且我的第一个代码是一个简单的IRC机器人,代码如下:
package main
import ("net"
"log"
"bufio"
"fmt"
"net/textproto"
)
type Bot struct{
server string
port string
nick string
user string
channel string
pass string
pread, pwrite chan string
conn net.Conn
}
func NewBot() *Bot {
return &Bot{server: "irc.freenode.net",
port: "6667",
nick: "subsaharan",
channel: "#rapidsms",
pass: "",
conn: nil,
user: "blaze"}
}
func (bot *Bot) Connect() (conn net.Conn, err error){
conn, err = net.Dial("tcp",bot.server + ":" + bot.port)
if err != nil{
log.Fatal("无法连接到IRC服务器", err)
}
bot.conn = conn
log.Printf("已连接到IRC服务器%s (%s)\n", bot.server, bot.conn.RemoteAddr())
return bot.conn, nil
}
func main(){
ircbot := NewBot()
conn, _ := ircbot.Connect()
conn.Write([]byte("NICK " + ircbot.nick))
conn.Write([]byte("JOIN " + ircbot.channel))
defer conn.Close()
reader := bufio.NewReader(conn)
tp := textproto.NewReader( reader )
for {
line, err := tp.ReadLine()
if err != nil {
break // 在错误时退出循环
}
fmt.Printf("%s\n", line)
}
}
当我运行这段代码时,终端输出如下:
2012/11/12 13:31:20 已连接到IRC服务器irc.freenode.net (193.219.128.49:6667)
:sendak.freenode.net NOTICE * :*** 正在查找您的主机名...
:sendak.freenode.net NOTICE * :*** 正在检查Ident
:sendak.freenode.net NOTICE * :*** 无法查找您的主机名
:sendak.freenode.net NOTICE * :*** 无Ident响应
ERROR :Closing Link: 127.0.0.1 (连接超时)
为什么连接一直超时?
英文:
I'm tinkering with golang and my first code is a simple IRC bot with the following code:
package main
import ("net"
"log"
"bufio"
"fmt"
"net/textproto"
)
type Bot struct{
server string
port string
nick string
user string
channel string
pass string
pread, pwrite chan string
conn net.Conn
}
func NewBot() *Bot {
return &Bot{server: "irc.freenode.net",
port: "6667",
nick: "subsaharan",
channel: "#rapidsms",
pass: "",
conn: nil,
user: "blaze"}
}
func (bot *Bot) Connect() (conn net.Conn, err error){
conn, err = net.Dial("tcp",bot.server + ":" + bot.port)
if err != nil{
log.Fatal("unable to connect to IRC server ", err)
}
bot.conn = conn
log.Printf("Connected to IRC server %s (%s)\n", bot.server, bot.conn.RemoteAddr())
return bot.conn, nil
}
func main(){
ircbot := NewBot()
conn, _ := ircbot.Connect()
conn.Write([]byte("NICK " + ircbot.nick))
conn.Write([]byte("JOIN " + ircbot.channel))
defer conn.Close()
reader := bufio.NewReader(conn)
tp := textproto.NewReader( reader )
for {
line, err := tp.ReadLine()
if err != nil {
break // break loop on errors
}
fmt.Printf("%s\n", line)
}
}
When I run this code I get the following output on the terminal:
2012/11/12 13:31:20 Connected to IRC server irc.freenode.net (193.219.128.49:6667)
:sendak.freenode.net NOTICE * :*** Looking up your hostname...
:sendak.freenode.net NOTICE * :*** Checking Ident
:sendak.freenode.net NOTICE * :*** Couldn't look up your hostname
:sendak.freenode.net NOTICE * :*** No Ident response
ERROR :Closing Link: 127.0.0.1 (Connection timed out)
Any reason why the connection keeps timing out?
答案1
得分: 21
conn.Write([]byte("NICK " + ircbot.nick + "\r\n"))
conn.Write([]byte("JOIN " + ircbot.channel + "\r\n"))
conn.Write([]byte("USER "+ircbot.nick+" 8 * :" + ircbot.nick + "\r\n"))
conn.Write([]byte("NICK " + ircbot.nick + "\r\n"))
conn.Write([]byte("JOIN " + ircbot.channel + "\r\n"))
fmt.Fprintf(conn, "USER %s 8 * :%s\r\n", ircbot.nick, ircbot.nick)
fmt.Fprintf(conn, "NICK %s\r\n", ircbot.nick)
fmt.Fprintf(conn, "JOIN %s\r\n", ircbot.channel)
fmt.Fprintf的第一个参数必须是满足io.Writer接口的任何类型。net.Conn的实现都满足这一点。因此,您可以将它们传递给任何期望io.Writer(或io.Reader)实现的函数。
英文:
All commands sent to an IRC server have a maximum of <strike>255</strike> 512 bytes and must be terminated with a carriage return and linefeed \r\n
.
conn.Write([]byte("NICK " + ircbot.nick + "\r\n"))
conn.Write([]byte("JOIN " + ircbot.channel + "\r\n"))
Additionally, freenode expects the USER
command to be first thing it sees from you.
conn.Write([]byte("USER "+ircbot.nick+" 8 * :" + ircbot.nick + "\r\n"))
conn.Write([]byte("NICK " + ircbot.nick + "\r\n"))
conn.Write([]byte("JOIN " + ircbot.channel + "\r\n"))
As a side note, you can make your life a little easier by using fmt.Fprintf
to format and send the data:
fmt.Fprintf(conn, "USER %s 8 * :%s\r\n", ircbot.nick, ircbot.nick)
fmt.Fprintf(conn, "NICK %s\r\n", ircbot.nick)
fmt.Fprintf(conn, "JOIN %s\r\n", ircbot.channel)
The first parameter of fmt.Fprintf
must be any type that satisfies the io.Writer
interface. The net.Conn
implementations all do this. As such you can pass them into any function which expects an io.Writer
(or io.Reader
for that matter) implementation.
答案2
得分: 3
此外,有时IRC服务器会发送一条“PING :cookie”的消息(例如,如果您的连接空闲时间过长)。您需要回复“PONG :cookie”。
英文:
Also, on occasion IRC servers will send a "PING :cookie" message (if for example your connection is idle for too long). You are expected to reply with "PONG :cookie".
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论