首頁 >後端開發 >Golang >如何在 Go 中使用 net.Conn.Read 可靠地處理持久 TCP 套接字的訊息幀?

如何在 Go 中使用 net.Conn.Read 可靠地處理持久 TCP 套接字的訊息幀?

Susan Sarandon
Susan Sarandon原創
2024-11-27 12:49:10336瀏覽

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

正確使用net.Conn.Read 來實現持久TCP 套接字

在Go 中,使用持久TCP 套接字涉及建立連接並不斷地進行操作讀取傳入的資料。 net.Conn.Read 函數負責從套接字檢索數據,但其行為可能不會立即清晰。

理解 TCP 中的訊息幀

與某些與其他協定相比,TCP 本身並不會提供訊息成幀。這意味著由應用程式定義一種在連續資料流中分隔訊息的方法。

有標頭的傳統訊息框架

在您之前的 C# 經驗中,訊息前面帶有包含訊息大小的標頭。這種方法允許接收應用程式知道後續訊息的確切長度。

Go 如何處理訊息處理

Go 採用了不同的方法。預設情況下,net.Conn.Read() 沒有確定訊息結束的固有機制。您在問題中提供的程式碼片段只是在循環中呼叫 conn.Read() ,而不考慮訊息邊界。這可能適用於某些場景,但它不是一個可靠或可擴展的解決方案。

解決方案:自訂訊息訊框

要正確處理持久 TCP 套接字,您需要實作自訂訊息框架。這涉及緩衝傳入資料並根據您自己定義的協定對其進行解析。

使用 bufio.Reader 的範例

一種建議的方法是使用內建 bufio .Reader 包裹您的網路。 Conn。此包裝器提供了附加功能,並使讀取資料更加有效率。

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)
    }
}

在此範例中,handleConnection 函數首先從連線中讀取單一位元組,表示後續訊息的長度。然後,它會建立一個緩衝區並使用 io.ReadFull 讀取指定大小的完整訊息。這允許應用程式無縫處理不同長度的訊息。

以上是如何在 Go 中使用 net.Conn.Read 可靠地處理持久 TCP 套接字的訊息幀?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn