我正在 GO 中創建一個 TCP 服務器端,它接收 TCP 數據包并相應地發送響應。我能夠監聽連接,但是當客戶端向服務器發送 TCP 數據包時,服務器僅在連接重置(TCP RST)時才會接收它們。這意味著當客戶端發送數據包時,服務器會等待下一個數據包對第一個數據包進行處理。這是影響這部分問題的代碼:listener, err := net.Listen("tcp", ":25565")if err != nil { fmt.Println(err)}for { conn, err := listener.Accept() if err != nil { fmt.Println(err) } message, _ := ioutil.ReadAll(conn) // Get the bytes from the TCP packet fmt.Println("Received connection " + conn.RemoteAddr().String()) HandlePacket(conn, message) // Do stuff with the data conn.Close() // End the connection}HandlePacket(...)解析數據包中接收到的字節。問題是,當客戶端發送第一個數據包時它什么也沒收到,然后在發送第二個數據包時打印第一個數據包的數據。
1 回答

婷婷同學_
TA貢獻1844條經驗 獲得超8個贊
重要的提示就在您從套接字讀取的調用中:
message, _ := ioutil.ReadAll(conn) // Get the bytes from the TCP packet
ReadAll()
不會只返回套接字緩沖區中的可用數據。ReadAll()
將一直讀取,直到再也沒有數據要讀取 - 直到流關閉。如您所見,僅當連接關閉時,流才會關閉。
您必須要求 TCP 套接字讀取一些有限數量的數據。由于 TCP 不保留消息邊界,因此您必須使用自己的成幀方案來知道要讀取多少數據。
一種這樣簡單的方案是使您的數據包始終具有固定大小。這可能很有用,例如,如果您要為某個游戲的網絡代碼發送流更新;只需讓每個數據包 256 字節,并在 256 字節中放入盡可能多的位置更新;如果有更多,只需發送更多數據包。
如果使用固定大小的幀對您不起作用,請考慮使用帶有小標題的數據包。也許前 4 個字節是一個整數,告訴您消息的長度,然后是消息。然后,每次要讀取數據包時,執行 4 個字節的硬讀取以找出大小,然后從套接字讀取那么多字節。
- 1 回答
- 0 關注
- 236 瀏覽
添加回答
舉報
0/150
提交
取消