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

时间:2016-01-11 08:50:45

标签: go connection bufferedreader reader

我有一个连接,就像这样创建:

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
}

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

为什么bufio.Reader.Read()有效,但net.Conn.Read()没有?

1 个答案:

答案 0 :(得分:9)

Conn.Read()方法是实现io.Reader,这是从任何字节源读取数据到[]byte的通用接口。引用Reader.Read()的文件:

  

读取最多读取len(p)个字节到p。

因此Read()最多可读取len(p)个字节,但由于您传递了nil个切片,因此无法读取任何内容(nil切片的长度为{ {1}})。请阅读链接的文档,了解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中,这意味着只有n的{​​{1}}个字节才有用(换句话说:buf)。

使用bufio.Reader的其他示例有效,因为您调用Reader.ReadString()并不需要buf[:n]参数。如果您使用bufio.Reader.Read()方法,则还必须传递非[]byte切片才能真正获得某些数据。