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

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

Susan Sarandon
發布: 2024-11-27 12:49:10
原創
389 人瀏覽過

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中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板