Go の net.Conn でのデータの正確な読み取り
Go ネットワーク アプリケーションの領域では、問題ネットからデータを正確に読み取ると、接続が発生する可能性があります。組み込みの Conn.Read 関数は便利ですが、サイズが制限されたユーザー定義のバイト配列にデータを読み取ります。これにより、実際のデータ サイズに応じて、バッファ割り当てが不十分または過剰になる可能性があります。
このジレンマに対処するには、強力な bufio パッケージを活用できます。 bufio は、必要に応じて内部バッファを動的に拡張することで、長さが不明なコンテンツを読み取るプロセスを効率化します。変更された例は次のとおりです。
package main import ( "bufio" "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() fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n") // Create a bufio.Scanner to read the response. scanner := bufio.NewScanner(conn) // Iterate over the lines of the response. for scanner.Scan() { line := scanner.Text() fmt.Println(line) } // Check for any errors that occurred during scanning. if err := scanner.Err(); err != nil { fmt.Println("scanner error:", err) } }
このコードは、net.Conn をソースとして bufio.Scanner オブジェクトを初期化します。スキャナは、ファイルの終わり (EOF) 条件またはエラーが発生するまで、継続的にデータを読み取ります。このアプローチでは、データがストリーミングされるときにバッファ拡張が自動的に処理され、正確かつ効率的な読み取りが保証されます。
あるいは、より直接的なアプローチとして、@fabrizioM が提案するように、io.Copy を利用することもできます:
func main() { conn, err := net.Dial("tcp", "google.com:80") if err != nil { fmt.Println("dial error:", err) return } defer conn.Close() fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n") // Create a bytes.Buffer to store the response. var buf bytes.Buffer io.Copy(&buf, conn) // Print the total size of the response. fmt.Println("total size:", buf.Len()) }
この例では、io.Copy を使用して net.Conn のコンテンツを bytes.Buffer に転送します。これは内部でバッファ割り当てと拡張。
以上がGo net.Conn からデータを正確に読み取るにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。