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