Utilisation appropriée de net.Conn.Read pour les sockets TCP persistants
Dans Go, travailler avec des sockets TCP persistants implique d'établir une connexion et de continuer lire les données entrantes. La fonction net.Conn.Read est responsable de la récupération des données du socket, mais son comportement peut ne pas être immédiatement clair.
Comprendre le cadrage des messages dans TCP
Contrairement à certains Avec d'autres protocoles, TCP ne fournit pas intrinsèquement de tramage de message. Cela signifie qu'il appartient à l'application de définir une méthode de séparation des messages au sein du flux de données continu.
Cadre de message traditionnel avec en-tête
Dans votre précédente expérience C#, les messages étaient précédés d'un en-tête contenant la taille du message. Cette approche permet à l'application réceptrice de connaître la longueur exacte du message suivant.
Comment Go gère la gestion des messages
Go adopte une approche différente. Par défaut, net.Conn.Read() ne dispose pas de mécanisme inhérent pour déterminer la fin d'un message. L'extrait de code que vous avez fourni dans votre question appelle simplement conn.Read() dans une boucle sans tenir compte des limites des messages. Cela peut fonctionner pour certains scénarios, mais ce n'est pas une solution fiable ou évolutive.
Solution : cadrage de messages personnalisé
Pour gérer correctement les sockets TCP persistants, vous devez implémenter cadrage de message personnalisé. Cela implique de mettre en mémoire tampon les données entrantes et de les analyser selon votre propre protocole défini.
Exemple d'utilisation de bufio.Reader
Une approche recommandée consiste à utiliser le bufio intégré .Reader pour envelopper votre net.Conn. Ce wrapper fournit des fonctionnalités supplémentaires et rend la lecture des données plus efficace.
import ( "bufio" "fmt" "io" "net" ) func main() { listener, err := net.Listen("tcp", ":8080") if err != nil { panic(err) } for { conn, err := listener.Accept() if err != nil { continue } go handleConnection(conn) } } func handleConnection(conn net.Conn) { defer conn.Close() r := bufio.NewReader(conn) for { size, err := r.ReadByte() if err != nil { return } buff := make([]byte, size) if _, err := io.ReadFull(r, buff); err != nil { return } fmt.Println("Received:", buff) } }
Dans cet exemple, la fonction handleConnection lit d'abord un seul octet de la connexion, représentant la longueur du message suivant. Il crée ensuite un tampon et utilise io.ReadFull pour lire le message complet de cette taille spécifiée. Cela permet à l'application de gérer de manière transparente des messages de différentes longueurs.
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!