亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

TCP 套接字:消息接收來自先前連接的消息的一部分

TCP 套接字:消息接收來自先前連接的消息的一部分

Go
慕尼黑8549860 2023-02-28 21:20:37
當來自上一個連接的消息的部分轉到下一個消息時,我不小心發現了一個錯誤。我有一個帶客戶端的基本服務器。我已經刪除了所有錯誤處理以避免示例過多膨脹。我也用 替換了一些Printf,time.Sleep因為我沒有機會及時斷開連接來重現錯誤,因為它讀取數據的速度太快了?!鞍笔且粋€簡單的結構,前 4 個字節是長度,然后是內容。客戶端代碼:package mainimport (    "encoding/binary"    "fmt"    "net")func main() {    conn, _ := net.Dial("tcp", "0.0.0.0:8081")    defer conn.Close()    str := "msadsakdjsajdklsajdklsajdk"    // Creating a package    buf := make([]byte, len(str)+4)    copy(buf[4:], str)    binary.LittleEndian.PutUint32(buf[:4], uint32(len(str)))    for {        _, err := conn.Write(buf)        if err != nil {            fmt.Println(err)            return        }    }}因此,出于某種原因,int32Buf接收前一條消息 (d, k) 的最后 2 個字節和長度的前 2 個字節,從而產生[107, 100, 26, 0]字節切片,而它應該是[26, 0, 0, 0]. 當然,其余數據包含剩余的兩個零:
查看完整描述

1 回答

?
浮云間

TA貢獻1829條經驗 獲得超4個贊

     conn.Read(int32Buf)

您需要檢查 conn.Read 的返回值并將其與您的預期進行比較。您在代碼中假設 conn.Read 將始終完全填充給定的 4 字節緩沖區。

這個假設是錯誤的,即它實際上可能讀取更少的數據。具體來說,它可能只讀取 2 個字節,在這種情況下,您最終會\x1a\x00\x00\x00在緩沖區中得到仍然轉換為 26 的消息長度。只是,消息的前 2 個字節實際上是長度的最后 2 個字節不包括在最后一次閱讀中。這意味著在讀取 26 個字節后,它不會讀取完整的消息。2 個字節是 leg 并將包含在下一條消息中 - 這就是您觀察到的。

要確保讀取緩沖區的確切大小,請檢查 conn.Read 的返回值或使用io.ReadFull。完成此操作后,它會按預期工作(來自評論):

好的,現在它完美無缺

那么為什么這只發生在新連接的上下文中呢?可能是因為另一個連接導致的額外負載稍微改變了行為,但足夠顯著。不過,這些不是從不同連接讀取的數據,而是與問題中的描述相反的當前連接讀取的數據。這可以通過對不同的客戶端使用不同的消息來輕松檢查。


查看完整回答
反對 回復 2023-02-28
  • 1 回答
  • 0 關注
  • 91 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號