为什么 conn.Read() 不向 [] 字节写入任何内容,但 bufio.Reader.ReadString() 有效?

Why does conn.Read() write nothing into a []byte, but bufio.Reader.ReadString() works?

我有一个连接,是这样创建的:

conn, err = net.Dial("tcp", "127.0.0.1:20000")

我试过以两种方式从这个连接中读取。我认为他们都必须工作,但第一个选项不行。

这是第一种方法:

var bytes []byte
for i := 0; i < 4; i++ {
    conn.Read(bytes)
}
fmt.Printf("%v", bytes)

这个方法的输出是:

[]

这是同样的事情,用 bufio.Reader:

完成
func readResponse(conn net.Conn) (response string, err error) {
    reader := bufio.NewReader(conn)
    _, err = reader.Discard(8)
    if err != nil {
        return
    }

    response, err = reader.ReadString('\n')

    return
}

此函数returns TCP 连接另一端的服务器给出的响应。

为什么 bufio.Reader.Read() 有效,而 net.Conn.Read() 无效?

Conn.Read() method is to implement io.Reader,从任何字节源读取数据到[]byte的通用接口。引用 Reader.Read() 的文档:

Read reads up to len(p) bytes into p.

所以 Read() 最多读取 len(p) 字节,但是由于您传递了 nil 切片,它不会读取任何内容(nil 切片的长度是 0).请阅读链接文档以了解 Reader.Read() 的工作原理。

Reader.Read() 没有分配缓冲区([]byte)来存储读取的数据,你必须创建一个并传递它,例如:

var buf = make([]byte, 100)
n, err := conn.Read(buf)
// n is the number of read bytes; don't forget to check err!

不要忘记始终检查返回的 error 如果到达数据末尾,则可能是 io.EOFio.Reader.Read()的通用合约还允许同时返回一些非nil错误(包括io.EOF)和一些读取数据(n > 0。读取的字节数将在 n 中,这意味着只有 buf 的前 n 个字节有用(换句话说:buf[:n])。

您使用 bufio.Reader works because you called Reader.ReadString() which doesn't require a []byte argument. If you would've used the bufio.Reader.Read() 方法的另一个示例,您还必须传递一个非 nil 切片才能实际获取一些数据。