Jump bufio.Scanner stops while reading TCP connection from Redis

Reading TCP connection between Redis server 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" appears in the result for the first scan, but the second scan only stops when the method is called Scan

. (marker00 → marker02 → marker00 and don't display anymore)

Why does it stop Scan

and how do I know the end of a TCP response (no use bufio.Reader

)?

+4


source to share


2 answers


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

Check it:



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")
}

      

+4


source


Old question, but I had the same problem. Two solutions:

1) Add "QUIT \ r \ n" command to your Redis post. This will force Redis to close the connection, which will stop scanning. You have to deal with the extra "+ OK" that quit prints.

2) Add



conn.SetReadDeadline(time.Now().Add(time.Second*5))

just before scanning. This will make the scan stop trying after 5 seconds. Unfortunately, it always takes 5 seconds to complete a scan, so choose this time wisely.

0


source







All Articles