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

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

Golang中的TCP固定大小消息成幀方法

Golang中的TCP固定大小消息成幀方法

Go
臨摹微笑 2022-06-13 10:49:27
我無法理解使用固定大小前綴長度標頭的消息框架是如何工作的。據說一個固定大小的字節數組將包含要發送的消息的長度。但是你將如何定義一個固定大小的字節數組,特別是在 Golang 中。說這是我的信息:Hello它的長度是 5。因此,如果我想通過 tcp 流發送它,為了確保我在另一端收到所有消息,我必須告訴它應該讀取多少字節。一個簡單的標題是length:message:5:Hello // [53 58 104 101 108 108 111]但是如果消息長度每次增長 10 倍,就會有更多的字節。所以標題大小是動態的。36:Hello, this is just a dumb question. // [51 54 58 72 101 108 108 111 44 32 116 104 105 115 32 105 115 32 106 117 115 116 32 97 32 100 117 109 98 32 113 117 101 115 116 105 111 110 46]所以這里36需要2個字節。我想到的一種方法是考慮協議的最大消息長度。假設 10KB = 10240 字節。然后將前導添加0到消息長度。這樣,我確定我將擁有一個固定的 5 字節標頭。這適用于所有情況嗎?如果是,如果我有超過 10KB 的消息,我應該將其拆分為 2 條消息嗎?如果不是,還有什么其他解決方案?我想在 Golang 中實現解決方案。更新 1:我讀過關于 Endians 的文章,盡管我無法理解他們做了什么會導致固定長度的字節。但是我在python中找到了一個示例,并嘗試以這種方式編寫它:客戶:    const maxLengthBytes = 8    conn, err := net.Dial("tcp", "127.0.0.1:9999")    if err != nil {        fmt.Println(err)        return    }    message := "Hello, this is just a dumb question"    bs := make([]byte, maxLengthBytes)    binary.LittleEndian.PutUint64(bs, uint64(len(text)))    bytes := append(bs, []byte(text)...)    conn.Write(bytes)服務器:    listener, err := net.ListenTCP("tcp", &net.TCPAddr{Port: 9999})    if err != nil {        fmt.Println(err)        return    }    for {        tcp, err := listener.AcceptTCP()        if err != nil {            fmt.Println(err)            continue        }        go Reader(tcp)    }func Reader(conn *net.TCPConn) {    foundLength := false    messageLength := 0    for {        if !foundLength {            var b = make([]byte, maxLengthBytes)            read, err := conn.Read(b)            if err != nil {                fmt.Println(err)                continue            }            if read != 8 {                fmt.Println("invalid header")                continue            }        }    }}
查看完整描述

1 回答

?
炎炎設計

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

請參考我在這篇文章中的回答 TCP client for Android: text is not received full

基本上,您必須定義數據如何存儲/格式化。例如:

  1. 我們將前綴長度存儲為int32(4 字節),小端。它和你的不一樣。

  2. 使用您的解決方案,長度是 a string,很難確定長度。對于您的解決方案,您必須使用固定長度的字符串。例如:10 個字符,并添加前導零。

對于您的問題。

  1. 它不適用于只有前綴長度的所有情況。它有它的局限性,例如如果我們使用int32前綴長度,消息的長度必須小于 Integer32.max,對嗎?

  2. 是的,我們必須拆分甚至合并(請參閱我在上面鏈接中的解釋)。

  3. 如果這是我們關心的問題,我們有很多方法來處理長度限制(實際上,幾乎應用程序協議都有最大請求大?。?。您可以多用一位來指示消息是否超過最大長度來解決它,對嗎?


查看完整回答
反對 回復 2022-06-13
  • 1 回答
  • 0 關注
  • 205 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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