Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go bufio.Scanner stops while reading TCP connection to Redis

Tags:

tcp

redis

go

Reading TCP connection between Redis-server by using bufio.Scanner

fmt.Fprintf(conn, "*3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$7\r\nHello!!\r\n")
scanner := bufio.NewScanner(conn)
for {
    // fmt.Println("marker00")
    if ok := scanner.Scan(); !ok {
        // fmt.Println("marker01")
        break
    }
    // fmt.Println("marker02")
    fmt.Println(scanner.Text())
}

"+OK" comes as the result for first scanning, but the second scanning stops just in invoking Scan method. (marker00 -> marker02 -> marker00 and no output any more)

Why does Scan stop and how can I know the end of TCP response (without using bufio.Reader)?

like image 435
otiai10 Avatar asked Aug 24 '14 06:08

otiai10


1 Answers

Redis does not close the connection for you after sending a command. Scan() ends after io.EOF which is not sent.

Check out this:

package main

import (
    "bufio"
    "fmt"
    "net"
)

// before go run, you must hit `redis-server` to wake redis up
func main() {
    conn, _ := net.Dial("tcp", "localhost:6379")
    message := "*3\r\n$3\r\nSET\r\n$1\r\na\r\n$1\r\nb\r\n"

    go func(conn net.Conn) {
        for i := 0; i < 10; i++ {
            fmt.Fprintf(conn, message)
        }
    }(conn)

    scanner := bufio.NewScanner(conn)
    for {
        if ok := scanner.Scan(); !ok {
            break
        }
        fmt.Println(scanner.Text())
    }
    fmt.Println("Scanning ended")
}
like image 112
Simon Zimmermann Avatar answered Oct 16 '22 15:10

Simon Zimmermann