net.conn read的时候一直等待是怎么回事呢?
1. 运行环境
go 1.20 系统Ubuntu22.04
2. 问题描述?
一个简单的监听tcp的代码 ,然后在浏览器请求127.0.0.1:9999, 这个时候浏览器一直没有返回, 到server端发现read一直在等待。reader.Read(buf[:])这句代码一直在等待
package main
import (
"bufio"
"fmt"
"net"
)
// TCP Server端测试
// 处理函数
func process(conn net.Conn) {
defer conn.Close() // 关闭连接
for {
reader := bufio.NewReader(conn)
var buf [64]byte
n, err := reader.Read(buf[:]) // 读取数据
if err != nil {
fmt.Println("read from client failed, err: ", err)
break
}
recvStr := string(buf[:n])
fmt.Println("收到Client端发来的数据:", recvStr)
conn.Write([]byte(recvStr)) // 发送数据
}
}
func main() {
listen, err := net.Listen("tcp", "127.0.0.1:9999")
if err != nil {
fmt.Println("Listen() failed, err: ", err)
return
}
for {
conn, err := listen.Accept() // 监听客户端的连接请求
fmt.Println(conn)
if err != nil {
fmt.Println("Accept() failed, err: ", err)
continue
}
go process(conn) // 启动一个goroutine来处理客户端的连接请求
}
}
3. 您期望得到的结果?
4. 您实际得到的结果?
可以看到 第一轮读取了64个字节以后 第二轮read就一直在等待 没有任何输出。这是为什么呢
第一次发送的是http协议头,是一个已\r\n\r\n结尾的包,你返回了数据,第二次连接里面已经没有数据了
别用
bufio.Reader
,直接用conn.Read(buf)
试试你可以看下 bufio.NewReader 里面的 Read 方法注释是什么
为啥要用bufio读,
用 io.ReadFull
第一轮 read 就把数据缓存到 bufio.Reader 对象的 buf 里面了,默认大小 4096,但你只取用了 64,他在等待下一次 conn 给他发数据,涉及到 epllo 的回调知识,协程目前被挂起了。