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 サイトの他の関連記事を参照してください。