14

私は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("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)
    }

}

このコードを実行すると、ターミナルに次の出力が表示されます。

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)

接続がタイムアウトし続ける理由は何ですか?

4

2 に答える 2

21

IRC サーバーに送信されるすべてのコマンドは、最大255,512バイトで、キャリッジ リターンとラインフィードで終了する必要があります\r\n

conn.Write([]byte("NICK " + ircbot.nick + "\r\n"))
conn.Write([]byte("JOIN " + ircbot.channel + "\r\n"))

さらに、freenode はUSERコマンドが最初に表示されることを期待しています。

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補足として、 を使用してデータをフォーマットして送信することで、生活を少し楽にすることができます。

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

于 2012-11-12T12:03:58.937 に答える
3

また、ときどき IRC サーバーが "PING :cookie" メッセージを送信します (たとえば、接続が長時間アイドル状態になっている場合)。「PONG :cookie」で返信する必要があります。

于 2014-06-18T19:38:59.993 に答える