为了账号安全,请及时绑定邮箱和手机立即绑定

bufio.NewReader ReadBytes - 同时读取多条消息

bufio.NewReader ReadBytes - 同时读取多条消息

Go
HUH函数 2022-06-21 15:49:04
我有这个侦听器函数,它在网络上侦听来自其对等方的消息。它必须正常工作,但是当它同时收到两条消息时,我收到以下错误:“💬 消息解码错误 - 缓冲区中有额外数据”这可以修改为同时允许多条消息吗?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 networkfunc 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`))}
查看完整描述

1 回答

?
阿晨1998

TA贡献2037条经验 获得超6个赞

应用程序在循环的每次迭代中创建并丢弃一个缓冲区。丢弃的缓冲区可以包含从连接中读取的未处理数据。


通过在循环之外创建 bufio.Reader 来修复。


该表达式的[]byte(`\n`)[0]计算结果为 byte \,而不是\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为. 在 SendMsgToPeer 中使用编码器。Peergob.NewEncoder(peer.conn)


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.")

    }

}


查看完整回答
反对 回复 2022-06-21
  • 1 回答
  • 0 关注
  • 188 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信