为什么 io.Copy 从套接字读取时有时会丢失行?

请帮助我了解观察到的从套接字读取的行为。


在实验中,发送方总是发送相同的行,以 '\n' 结尾,然后关闭套接字的写入端。


接收端的此代码按预期工作,打印每一行:


    rdr := bufio.NewReader(sock)

    for {

        b, err := rdr.ReadBytes('\n')

        if err != nil {

            break

        }

        fmt.Print(string(b))

    }

然而,这段代码


n, err := io.Copy(os.Stdout, sock)

有时会从数据块的开头跳过随机数量的行,并且只打印其余的行(n相应地更改,并且err始终为零)。


Thesock是一种自定义类型,它抽象了net.TCPConn和tls.Conn,否则将在整个代码库中使用,而不会出现问题。


为什么 read by 开头的行io.Copy有时会丢失?


函数式编程
浏览 81回答 1
1回答

蝴蝶刀刀

bufio.Reader实现io.Reader对象的缓冲。这是什么意思?如果您使用 abufio.Reader从io.Reader源读取数据,它可能会从其源(并缓冲它)读取比您直接从其bufio.Reader本身读取的数据更多的数据。这意味着如果您使用 abufio.Reader从sock第一个读取,然后使用io.Copy(),可能有一些数据已经读取sock并位于bufio.Reader的内部缓冲区中,这些数据io.Copy()将看不到也不会复制。你不应该在同一个io.Reader来源上混合这两个。如果必须,请务必先排空bufio.Reader's 缓冲区,然后像这样继续复制sock:// First drain the buffer:n, err := io.Copy(os.Stdout, rdr)// Handle error// Then proceed with the socket:n, err = io.Copy(os.Stdout, sock)// Handle error
打开App,查看更多内容
随时随地看视频慕课网APP