簡體   English   中英

bufio.NewReader ReadBytes - 同時讀取多條消息

[英]bufio.NewReader ReadBytes - Reading multiple message at the same time

我有這個監聽器 function 在網絡上監聽來自其對等方的消息。

它必須正常工作,但是當它同時收到兩條消息時,我收到以下錯誤:

“消息解碼錯誤 - 緩沖區中有額外數據”

這可以修改為同時允許多條消息嗎?

func Listen(peer Peer) {

    log.Info("👂 Listening for messages from: ", peer.Address)

    for {
        //will listen for message to process ending in newline (\n)
        msg, msgErr := bufio.NewReader(peer.conn).ReadBytes([]byte(`\n`)[0])
        if msgErr == io.EOF {
            peer.conn.Close()
        } else if msgErr == nil {
            msg, err := hex.DecodeString(string(msg[:len(msg)-1]))
            mgsDecoded, decodeErr := DeserializeMessage(msg[:])

            if decodeErr == nil { 
                // use decoded message here
            } else {
                log.Warn("💬 Message Decode error - ", decodeErr)
            }

        }
    }
}

//DeserializeMessage - Decode our message from a byte array to
//networkMessage *NetworkMessage
//over the network
func DeserializeMessage(serialized_bytes []byte) (NetworkMessage, error) {
    // Create new buffer and decoder
    buf := bytes.NewBuffer(serialized_bytes)
    enc := gob.NewDecoder(buf)
    // Create new Block Instance to load the serialized block into
    var networkMessage NetworkMessage
    err := enc.Decode(&networkMessage)
    return networkMessage, err
}

添加了我們發送消息的方式:


func SendMsgToPeer(networkMessage NetworkMessage, peer Peer) {

    log.Debug("💬 Message Sent -> Peer: ", peer.Address,
        " Command: ", string(networkMessage.Command),
        " Payload: ", string(utils.TruncateString(networkMessage.Payload, 50)))

    msg, err := networkMessage.SerializeMessage()
    if err != nil {
        log.Warn("❌ Error encoding message.")
    }

    peer.conn.Write([]byte(hex.EncodeToString(msg)))
    peer.conn.Write([]byte(`\n`))
}

應用程序在循環的每次迭代中創建並丟棄一個緩沖區。 丟棄的緩沖區可以包含從連接中讀取的未處理數據。

通過在循環之外創建 bufio.Reader 來修復。

表達式[]byte(`\n`)[0]計算為字節\ ,而不是\n 通過指定\n作為分隔符來修復。

br := bufio.NewReader(peer.conn)
for {
    //will listen for message to process ending in newline (\n)
    msg, msgErr := br.ReadBytes('\n')
    ...

客戶端將消息終止符寫為兩個字節\n 通過使用解釋的字符串文字而不是原始字符串文字,將客戶端更改為寫入單字節\n

peer.conn.Write([]byte("\n"))

如果您可以刪除使用換行符分隔的十六進制編碼消息的要求,那么您可以直接使用 gob 解碼器:

func Listen(peer Peer) {
    defer peer.conn.Close()
    log.Info("👂 Listening for messages from: ", peer.Address)
    dec := gob.NewDecoder(peer.conn)
    for {
       var networkMessage NetworkMessage
       err := dec.Decode(&networkMessage)
       if err != nil {
          log.Info("decode error:", err)
          return
        }
        // do something with networkMessage
    }
}

對客戶端代碼進行相應的更改。 將字段enc *gob.Encoder添加到Peer並將字段初始化為gob.NewEncoder(peer.conn) 在 SendMsgToPeer 中使用編碼器。

func SendMsgToPeer(networkMessage NetworkMessage, peer Peer) {
    log.Debug("💬 Message Sent -> Peer: ", peer.Address,
        " Command: ", string(networkMessage.Command),
        " Payload: ", string(utils.TruncateString(networkMessage.Payload, 50)))
    err := peer.enc.Encode(networkMessage)
    if err != nil {
        log.Warn("❌ Error encoding message.")
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM