Golang中的TCP固定大小消息成幀方法
我無(wú)法理解使用固定大小前綴長(zhǎng)度標(biāo)頭的消息框架是如何工作的。據(jù)說(shuō)一個(gè)固定大小的字節(jié)數(shù)組將包含要發(fā)送的消息的長(zhǎng)度。但是你將如何定義一個(gè)固定大小的字節(jié)數(shù)組,特別是在 Golang 中。說(shuō)這是我的信息:Hello它的長(zhǎng)度是 5。因此,如果我想通過 tcp 流發(fā)送它,為了確保我在另一端收到所有消息,我必須告訴它應(yīng)該讀取多少字節(jié)。一個(gè)簡(jiǎn)單的標(biāo)題是length:message:5:Hello // [53 58 104 101 108 108 111]但是如果消息長(zhǎng)度每次增長(zhǎng) 10 倍,就會(huì)有更多的字節(jié)。所以標(biāo)題大小是動(dòng)態(tài)的。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個(gè)字節(jié)。我想到的一種方法是考慮協(xié)議的最大消息長(zhǎng)度。假設(shè) 10KB = 10240 字節(jié)。然后將前導(dǎo)添加0到消息長(zhǎng)度。這樣,我確定我將擁有一個(gè)固定的 5 字節(jié)標(biāo)頭。這適用于所有情況嗎?如果是,如果我有超過 10KB 的消息,我應(yīng)該將其拆分為 2 條消息嗎?如果不是,還有什么其他解決方案?我想在 Golang 中實(shí)現(xiàn)解決方案。更新 1:我讀過關(guān)于 Endians 的文章,盡管我無(wú)法理解他們做了什么會(huì)導(dǎo)致固定長(zhǎng)度的字節(jié)。但是我在python中找到了一個(gè)示例,并嘗試以這種方式編寫它:客戶: 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)服務(wù)器: 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 } } }}
查看完整描述