Heim >Backend-Entwicklung >Golang >Wie kann ich das Message Framing mit net.Conn.Read in Go für persistente TCP-Sockets zuverlässig handhaben?
Richtige Verwendung von net.Conn.Read für persistente TCP-Sockets
In Go umfasst die Arbeit mit persistenten TCP-Sockets den kontinuierlichen Aufbau einer Verbindung Eingehende Daten lesen. Die net.Conn.Read-Funktion ist für das Abrufen von Daten aus dem Socket verantwortlich, ihr Verhalten ist jedoch möglicherweise nicht sofort klar.
Nachrichtenframing in TCP verstehen
Im Gegensatz zu einigen anderen Im Gegensatz zu anderen Protokollen bietet TCP grundsätzlich kein Nachrichten-Framing. Dies bedeutet, dass es Sache der Anwendung ist, eine Methode zum Trennen von Nachrichten innerhalb des kontinuierlichen Datenstroms zu definieren.
Traditionelles Message Framing mit Header
In Ihrer bisherigen C#-Erfahrung: Den Nachrichten wurde ein Header mit der Nachrichtengröße vorangestellt. Dieser Ansatz ermöglicht es der empfangenden Anwendung, die genaue Länge der nachfolgenden Nachricht zu kennen.
Wie Go die Nachrichtenverarbeitung handhabt
Go verfolgt einen anderen Ansatz. Standardmäßig verfügt net.Conn.Read() nicht über einen inhärenten Mechanismus, um das Ende einer Nachricht zu bestimmen. Der Codeausschnitt, den Sie in Ihrer Frage angegeben haben, ruft einfach conn.Read() in einer Schleife auf, ohne Nachrichtengrenzen zu berücksichtigen. Dies kann für bestimmte Szenarien funktionieren, ist aber keine zuverlässige oder skalierbare Lösung.
Lösung: Benutzerdefiniertes Nachrichten-Framing
Um persistente TCP-Sockets richtig zu handhaben, müssen Sie Folgendes implementieren Benutzerdefinierter Nachrichtenrahmen. Dazu gehört das Puffern der eingehenden Daten und das Parsen gemäß Ihrem eigenen definierten Protokoll.
Beispiel mit bufio.Reader
Ein empfohlener Ansatz ist die Verwendung des integrierten bufio .Reader zum Einwickeln Ihres Netzes.Conn. Dieser Wrapper bietet zusätzliche Funktionalität und macht das Lesen von Daten effizienter.
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) } }
In diesem Beispiel liest die Funktion handleConnection zunächst ein einzelnes Byte aus der Verbindung, das die Länge der nachfolgenden Nachricht darstellt. Anschließend wird ein Puffer erstellt und io.ReadFull verwendet, um die vollständige Nachricht der angegebenen Größe zu lesen. Dadurch kann die Anwendung Nachrichten unterschiedlicher Länge nahtlos verarbeiten.
Das obige ist der detaillierte Inhalt vonWie kann ich das Message Framing mit net.Conn.Read in Go für persistente TCP-Sockets zuverlässig handhaben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!