Lecture de données de longueur variable dans Go avec net.Conn.Read
Lorsque vous travaillez avec des applications réseau dans Go, vous rencontrez souvent des situations où les données reçues via une connexion sont de longueur variable. net.Conn de la bibliothèque standard fournit une méthode appelée Read, qui remplit un tableau d'octets avec les données reçues. Cependant, cette approche peut être problématique si vous ne connaissez pas la longueur exacte du contenu à l'avance et peut entraîner une lecture de données trop ou insuffisantes.
Pour relever ce défi, une approche consiste à utiliser le bufio emballer. Cependant, une solution plus efficace consiste à utiliser un tampon croissant et à lire les données jusqu'à ce que la fin du fichier (EOF) soit rencontrée :
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)) }
Cette solution alloue un tampon initial important et l'étend progressivement au fur et à mesure. les données sont reçues. Il continue la lecture jusqu'à ce que l'EOF soit atteint, garantissant que le tampon contient la réponse complète. De plus, il garde une trace de la taille totale des données reçues.
Vous pouvez également utiliser le type bytes.Buffer en conjonction avec io.Copy pour obtenir un résultat similaire :
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()) }
Cette approche utilise un tampon qui s'étend automatiquement selon les besoins et fournit une solution plus propre et plus concise.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!