登录
首页 >  Golang >  Go问答

为何 io.Copy 在读取套接字时会丢失行?

来源:stackoverflow

时间:2024-03-08 22:45:26 231浏览 收藏

最近发现不少小伙伴都对Golang很感兴趣,所以今天继续给大家介绍Golang相关的知识,本文《为何 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 始终为 nil)。

sock 是一种自定义类型,它抽象了 net.tcpconntls.conn,否则在整个代码库中使用都不会出现问题。

为什么 io.copy 读取的开头行有时会丢失?


正确答案


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

这意味着,如果您首先使用 bufio.readersock 读取,然后使用 io.Copy(),则可能已经从 sock 读取了一些数据并位于 bufio.reader 的内部缓冲区中,其中 io.copy( ) 不会看到也不会复制。

您不应该在同一个 io.reader 源上混合这两个。如果必须,请务必首先排空 bufio.reader 的缓冲区,然后继续从 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

今天带大家了解了的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>