我有一个连接,就像这样创建:
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()
没有?
答案 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.EOF
。 io.Reader.Read()
的一般合同还允许同时返回一些非nil
错误(包括io.EOF
)和一些读取数据(n > 0
) 。读取字节数将在n
中,这意味着只有n
的{{1}}个字节才有用(换句话说:buf
)。
使用bufio.Reader
的其他示例有效,因为您调用Reader.ReadString()
并不需要buf[:n]
参数。如果您使用bufio.Reader.Read()
方法,则还必须传递非[]byte
切片才能真正获得某些数据。