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