首页  >  文章  >  后端开发  >  如何从 Go 中的'net.Conn”读取块数据?

如何从 Go 中的'net.Conn”读取块数据?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-11-09 12:36:02667浏览

How to Read Data in Chunks from a `net.Conn` in Go?

使用 Go 的 net.Conn.Read 读取数据块

在 Go 中,您可以使用 net.Conn.Read 访问原始网络连接,它读取传入的数据包到一个字节数组中。但是,当您不知道传入数据的确切大小时,读入固定大小的数组可能会导致数据截断或不必要的缓冲。

要处理此问题,您可以采用更灵活的方法,使用bufio 包或替代技术。

使用 bufio

bufio 包提供 Reader 类型,它允许您以块的形式读取数据。您可以从 net.Conn 连接创建 Reader 对象,然后使用 ReadSlice 或 ReadBytes 方法读取数据,直到遇到特定分隔符或到达输入末尾。例如,要读取数据直到数据包末尾,您可以使用以下代码:

package main

import (
    "bufio"
    "fmt"
    "net"
)

func main() {
    conn, err := net.Dial("tcp", "google.com:80")
    if err != nil {
        fmt.Println("dial error:", err)
        return
    }
    defer conn.Close()

    // Create a bufio.Reader from the net.Conn
    reader := bufio.NewReader(conn)

    // Read data in chunks until the end of the packet
    buf := []byte{}
    for {
        chunk, err := reader.ReadSlice('\n')
        if err != nil {
            if err != io.EOF {
                fmt.Println("read error:", err)
            }
            break
        }
        buf = append(buf, chunk...)
    }
    fmt.Println("total size:", len(buf))
    // fmt.Println(string(buf))
}

替代方法

或者,您可以使用 bytes.Buffer 类型来附加传入的数据数据块并累加总大小:

package main

import (
    "bytes"
    "fmt"
    "io"
    "net"
)

func main() {
    conn, err := net.Dial("tcp", "google.com:80")
    if err != nil {
        fmt.Println("dial error:", err)
        return
    }
    defer conn.Close()

    // Create a bytes.Buffer to accumulate incoming data
    var buf bytes.Buffer

    // Copy data from the net.Conn to the Buffer
    if _, err = io.Copy(&buf, conn); err != nil {
        fmt.Println("copy error:", err)
    }

    fmt.Println("total size:", buf.Len())
}

通过使用其中一种方法,您可以处理不同的数据长度,而无需数据截断或过多缓冲,从而确保 Go 中通过网络连接进行高效的数据传输。

以上是如何从 Go 中的'net.Conn”读取块数据?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn