Maison >développement back-end >Golang >Comment gérer de manière fiable le cadrage des messages avec net.Conn.Read dans Go pour les sockets TCP persistants ?

Comment gérer de manière fiable le cadrage des messages avec net.Conn.Read dans Go pour les sockets TCP persistants ?

Susan Sarandon
Susan Sarandonoriginal
2024-11-27 12:49:10336parcourir

How to Reliably Handle Message Framing with net.Conn.Read in Go for Persistent TCP Sockets?

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn