为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
函数式编程 2022-10-24 16:04:49
请帮助我了解观察到的从套接字读取的行为。在实验中,发送方总是发送相同的行,以 '\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有时会丢失?
查看完整描述

1 回答

?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

bufio.Reader实现io.Reader对象的缓冲。这是什么意思?如果您使用 abufio.Readerio.Reader源读取数据,它可能会从其源(并缓冲它)读取比您直接从其bufio.Reader本身读取的数据更多的数据。

这意味着如果您使用 abufio.Readersock第一个读取,然后使用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


查看完整回答
反对 回复 2022-10-24
  • 1 回答
  • 0 关注
  • 95 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信