【问题标题】:Go bufio.Scanner stops while reading TCP connection to RedisGo bufio.Scanner 在读取到 Redis 的 TCP 连接时停止
【发布时间】:2014-08-24 06:44:54
【问题描述】:

使用bufio.Scanner读取Redis-server之间的TCP连接

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" 是第一次扫描的结果,但第二次扫描在调用Scan 方法时停止。 (marker00 -> marker02 -> marker00 不再有输出)

为什么Scan 会停止,我如何知道 TCP 响应结束(不使用 bufio.Reader)?

【问题讨论】:

  • 它确实适用于一个简单的字符串 (play.golang.org/p/Z3oMRi5A0g),所以它应该在这里指出第一个 Scan() 的输出不知何故得到了 conn 的全部内容。你试过scanner := bufio.NewScanner(bufio.NewReader(conn))吗?
  • @VonC 感谢您的评论!是的,我尝试了 NewReader 的 NewScanner。在这种情况下,conn 响应的全部内容将只有“+OK”。 (@见pbs.twimg.com/media/BvyUw1ECQAE3vaQ.jpg
  • 您设法获得的唯一scanner.Text() 的第一个输出是什么?
  • 它是“+OK”,我想要足够的响应,但问题是它永远不会结束。 (我做了一个要点来重现这个问题gist.github.com/otiai10/3cf030e2f7816a59347f如果你不介意检查)
  • 你期待什么? Redis 在发送命令后不会为您关闭连接。 Scan() 在未发送的 io.EOF 之后结束。

标签: tcp go redis


【解决方案1】:

Redis 在发送命令后不会为你关闭连接。 Scan() 在未发送的 io.EOF 之后结束。

看看这个:

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

【讨论】:

  • 谢谢!我可以理解为什么Scan 停止并意识到我必须实现一些函数来判断消息响应的结束(如果使用bufio.Scanner)。
【解决方案2】:

老问题,但我有同样的问题。两种解决方案:

1) 在 Redis 消息中添加“QUIT\r\n”命令。这将导致 Redis 关闭将终止扫描的连接。您必须处理退出输出的额外“+OK”。

2) 添加

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

就在您开始扫描之前。这将导致扫描在 5 秒后停止尝试。不幸的是,完成扫描总是需要 5 秒钟,所以请明智地选择这个时间。

【讨论】:

    猜你喜欢
    • 2019-04-30
    • 2015-01-12
    • 2015-05-02
    • 2019-11-30
    • 1970-01-01
    • 2021-12-13
    • 2011-05-10
    • 1970-01-01
    • 2011-06-22
    相关资源
    最近更新 更多