我有一个连接,像这样创建:
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()
不是?
该Conn.Read()
方法是实现io.Reader
,通用接口从任何字节源读取数据到一个[]byte
.引用文档Reader.Read()
:
读取读取最多len(p)个字节到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.EOF
如果达到数据结束.的常规协定io.Reader.Read()
还允许返回一些非nil
错误(包括io.EOF
)和一些读取数据(n > 0
)在同一时间.读取的字节数将在n
,这意味着只有第一个n
字节buf
是有用的(换句话说:) buf[:n]
.
你使用的另一个例子bufio.Reader
是因为你调用了Reader.ReadString()
不需要[]byte
参数的.如果您将使用该bufio.Reader.Read()
方法,则还必须传递非nil
切片以实际获取某些数据.