ホームページ >バックエンド開発 >Golang >Go でネットワーク接続から可変長データを読み取る方法は?

Go でネットワーク接続から可変長データを読み取る方法は?

Barbara Streisand
Barbara Streisandオリジナル
2024-11-09 11:05:02990ブラウズ

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

net.Conn.Read を使用した Go での可変長データの読み取り

Go でネットワーク アプリケーションを操作する場合、次のような状況によく遭遇します。接続を通じて受信されるデータは可変長です。標準ライブラリの net.Conn には、受信したデータをバイト配列に格納する Read というメソッドが用意されています。ただし、コンテンツの正確な長さが事前に分からない場合、このアプローチでは問題が発生する可能性があり、読み取りデータが多すぎるか不十分になる可能性があります。

この課題に対処する 1 つのアプローチは、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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。