20210217关于net.Conn的几种读取方式以及EOF是什么 - ziyouzy/2021blog GitHub Wiki
-
关于net.Conn的读取方式一直让我疑惑的是除了Net.Conn.Read()方法之外还有一种ioutil.ReadAll(net.Conn)的方式,为什么呢?
其实这里和linux的一切皆文件哲学联系起来了:socket不仅仅拥有全双工的特性,同时他也拥有文件的特性,这也是为什么既可以直接Net.Conn.Read(&buf)也可以通过ioutil.ReadAll(conn)的原因
后者是将conn当作一个“文件的对象实体”来操作了
而前者则是使用这个“文件对象”自身所拥有的方法 -
EOF是什么
首先EOF不只是存在于golang中,c/c++也存在同样的EOF,他的含义也是相同的,都代表读取到了文件的末尾 或者说,任何文件,如txt这样的文件如果不停的读也都可以最后读到一个同样的EOF标识
对于socket编程中大致的使用方式如下
if err != io.EOF {
log.Printf("Read error: %s",err)
}
注意,io.Eof仅仅是“文件的末尾”,或者说是一个操作符号,取决于发送端,或者说你自己所设计的沟通方式是否需要在每次发送时添加这个io.Eof符号(似乎这个符号的16进制数的具象化表示是-1)
io.Eof并不代表错误
真正的错误,在这里特指net.Conn的连接终端是:net.OpError
他和io.Eof似乎都是常量,我去看看他们到底分别是什么:
在io包源文件中EOF是个这样的存在:
var EOF = errors.New("EOF")
可以理解成他把一个“错误”当常量来用了
而net.OpError则要复杂很多,他在net.go文件中是个结构类:
type OpError struct {
Op string
Net string
Source Addr
Addr Addr
Err error
}
OpError{}包含多个方法,其中一个是实现error接口的方法,因此他也是个error