英文:
Go bufio.Scanner stops while reading TCP connection to Redis
问题
使用bufio.Scanner
读取Redis服务器之间的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 {
if ok := scanner.Scan(); !ok {
break
}
fmt.Println(scanner.Text())
}
第一次扫描的结果是"+OK",但第二次扫描在调用Scan
方法时停止了(marker00 -> marker02 -> marker00,之后没有输出了)。
为什么Scan
会停止,而且如何在不使用bufio.Reader
的情况下知道TCP响应的结束?
英文:
Reading TCP connection between Redis-server by using bufio.Scanner
<!-- language: go -->
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
)?
答案1
得分: 5
Redis在发送命令后不会自动关闭连接。Scan()在未发送io.EOF时结束。
请查看以下代码:
package main
import (
"bufio"
"fmt"
"net"
)
// 在运行之前,你需要启动`redis-server`来唤醒Redis
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("扫描结束")
}
希望对你有帮助!
英文:
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")
}
答案2
得分: 0
旧问题,但我遇到了同样的问题。有两种解决方案:
1)在你的Redis消息中添加一个"QUIT\r\n"命令。这将导致Redis关闭连接,从而终止扫描。你需要处理额外的" +OK"输出。
2)在开始扫描之前添加conn.SetReadDeadline(time.Now().Add(time.Second*5))
。这将导致扫描在5秒后停止尝试。不幸的是,完成扫描始终需要5秒,所以要明智地选择这个时间。
英文:
Old question, but I had the same issue. Two solutions:
-
Add a "QUIT\r\n" command to your Redis message. This will cause Redis to close the connection which will terminate the scan. You'll have to deal with the extra "+OK" that the quit outputs.
-
Add
conn.SetReadDeadline(time.Now().Add(time.Second*5))
just before you start scanning. This will cause the scan to stop trying after 5 seconds. Unfortunately, it will always take 5 seconds to complete the scan so choose this time wisely.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论