简单的golang IRC机器人一直超时

huangapple go评论80阅读模式
英文:

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(&quot;NICK &quot; + ircbot.nick + &quot;\r\n&quot;))
conn.Write([]byte(&quot;JOIN &quot; + ircbot.channel + &quot;\r\n&quot;))

Additionally, freenode expects the USER command to be first thing it sees from you.

conn.Write([]byte(&quot;USER &quot;+ircbot.nick+&quot; 8 * :&quot; + ircbot.nick + &quot;\r\n&quot;))
conn.Write([]byte(&quot;NICK &quot; + ircbot.nick + &quot;\r\n&quot;))
conn.Write([]byte(&quot;JOIN &quot; + ircbot.channel + &quot;\r\n&quot;))

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, &quot;USER %s 8 * :%s\r\n&quot;, ircbot.nick, ircbot.nick)
fmt.Fprintf(conn, &quot;NICK %s\r\n&quot;, ircbot.nick)
fmt.Fprintf(conn, &quot;JOIN %s\r\n&quot;, 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".

huangapple
  • 本文由 发表于 2012年11月12日 18:33:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/13342128.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定