我正在嘗試通過 TCP 在 GoLang 中發(fā)送和接收 protobuff 編碼的消息,發(fā)送方可以write()在操作中途取消,接收方可以正確接收部分消息。請注意,我使用單個 TCP 連接無限發(fā)送不同用戶定義類型的消息(這不是每個連接消息的情況)為了具體解釋我的問題,首先我將介紹如何在沒有部分寫入的情況下實現(xiàn)發(fā)送/接收。在我的程序中,有多種類型的消息,定義在一個.proto文件中。我將解釋一種這樣的消息類型的機制。message MessageType { int64 sender = 1; int64 receiver = 2; int64 operation = 3; string message = 4;}然后我使用 Golang Protobuf 插件生成存根。然后在發(fā)送方,下面是我發(fā)送的方式。func send(w *bufio.Writer, code uint8, oriMsg MessageType) { err := w.WriteByte(code) data, err := proto.Marshal(oriMsg) lengthWritten := len(data) var b [8]byte bs := b[:8] binary.LittleEndian.PutUint64(bs, uint64(lengthWritten)) _, err = w.Write(bs) _, err = w.Write(data) w.flush()}然后在receiver端,下面是我的接收方式。reader *bufio.Readerfor true { if msgType, err = reader.ReadByte(); err != nil { panic() } if msgType == 1 || msgType == 2{ var b [8]byte bs := b[:8] _, err := io.ReadFull(reader, bs) numBytes := binary.LittleEndian.Uint64(bs) data := make([]byte, numBytes) length, err := io.ReadFull(reader, data) msg *MessageType = new(GenericConsensus) // an empty message err = proto.Unmarshal(data[:length], msg) // do something with the message } else { // unknown message type handler } }現(xiàn)在我的問題是,如果發(fā)件人在中間中止他的寫入怎么辦:更具體地說,情況 1:如果發(fā)送方寫入消息類型字節(jié),然后中止怎么辦?在這種情況下,接收方將讀取消息類型字節(jié),并等待接收 8 字節(jié)的消息長度,但發(fā)送方不發(fā)送它。情況 2:這是情況 1 的擴展版本,其中發(fā)送方首先僅發(fā)送消息類型字節(jié),中止發(fā)送消息長度和編組消息,然后發(fā)送下一條消息:類型字節(jié)、長度和編碼消息?,F(xiàn)在在接收方,一切都出錯了,因為違反了消息的順序(類型、長度和編碼消息)。所以我的問題是,如何修改接收方,使其在發(fā)送方違反預(yù)先約定的 type:length:encoded-message 順序的情況下仍能繼續(xù)運行?
1 回答

慕少森
TA貢獻2019條經(jīng)驗 獲得超9個贊
為什么發(fā)件人會中止一條消息,然后發(fā)送另一條消息?你的意思是它是一個完全拜占庭式的發(fā)件人?還是您正在準(zhǔn)備進行模糊測試?
如果您的 API 合同規(guī)定發(fā)送方始終需要發(fā)送正確的消息,那么接收方可以簡單地忽略錯誤消息,甚至可以在發(fā)現(xiàn)違反 API 合同的情況下關(guān)閉連接。
如果你真的需要它,這里有一些關(guān)于如何讓它工作的想法:
從一個獨特的序言開始——但是你必須確保這個序言永遠不會出現(xiàn)在數(shù)據(jù)中
在將消息發(fā)送到解碼器之前向消息添加校驗和。所以完整的數(shù)據(jù)包將是
[msg_type : msg_len : msg : chksum ]
:這允許接收方檢查它是正確的消息還是格式錯誤的消息。
此外,就目前的代碼而言,發(fā)送最大 64 位的大小很容易導(dǎo)致崩潰。所以你還應(yīng)該檢查大小是否在一個有用的范圍內(nèi)。我會將其限制為 32 位...
- 1 回答
- 0 關(guān)注
- 121 瀏覽
添加回答
舉報
0/150
提交
取消