首頁  >  文章  >  後端開發  >  如何在 Go 中從網路連線讀取可變長度資料?

如何在 Go 中從網路連線讀取可變長度資料?

Barbara Streisand
Barbara Streisand原創
2024-11-09 11:05:02952瀏覽

How to Read Variable-Length Data from a Network Connection in Go?

在Go 中使用net.Conn.Read 讀取可變長度資料

在Go 中使用網路應用程式時,您經常會遇到以下情況:透過連接接收的資料的長度是可變的。標準函式庫的net.Conn提供了一個名為Read的方法,它用接收到的資料填入位元組數組。然而,如果您事先不知道內容的確切長度,這種方法可能會出現問題,並可能導致讀取太多​​或不足的資料。

要解決這個挑戰,一個方法是利用 bufio包裹。然而,更有效的解決方案是採用不斷增長的緩衝區並讀取數據,直到遇到文件結尾(EOF):

package main

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

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

    // Write a request to the connection.
    fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")

    // Create a buffer to store the received data.
    buf := make([]byte, 0, 4096)

    // Read from the connection in a loop until EOF.
    for {
        // Read into a temporary buffer to avoid overwriting existing data in `buf`.
        tmp := make([]byte, 256)
        n, err := conn.Read(tmp)
        if err != nil {
            if err != io.EOF {
                fmt.Println("read error:", err)
            }
            break
        }

        // Append the new data to the buffer.
        buf = append(buf, tmp[:n]...)
    }

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

此解決方案分配相當大的初始緩衝區,並逐漸將其擴展為更多收到資料。它繼續讀取直到到達 EOF,確保緩衝區包含完整的回應。此外,它還追蹤接收到的資料的總大小。

或者,您可以將bytes.Buffer 類型與io.Copy 結合使用來實現類似的結果:

package main

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

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

    // Write a request to the connection.
    fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")

    // Create a buffer to store the received data.
    var buf bytes.Buffer

    // Copy the data from the connection into the buffer.
    io.Copy(&buf, conn)

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

這種方法使用一個可以根據需要自動擴展的緩衝區,並提供更乾淨、更簡潔的解決方案。

以上是如何在 Go 中從網路連線讀取可變長度資料?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn