dtpyvb1873 2018-09-26 21:43
浏览 1574
已采纳

在Go中使用conn.Read()读取前几个字节后,如何继续读取其余字节?

I am trying to read from a tcp connection in Go. I have a specific header format I am trying to parse first. So read the first 12 bytes which has the info associated with the header. And that tells me that the remaining message length is a certain amount of bytes. In this case 1607 bytes. I tried the following code where I read the header bytes, and then tried to read the remaining bytes.

import ("net"
        log "github.com/sirupsen/logrus"
       "bytes"
       "encoding/binary"
)

func handleRequest(conn net.Conn) {

    // Structs to make header parsing easiers
    type encapSTHdrMsgType uint16
    type encapSTHdrMsgEncap uint16
    type encapSTHdr struct {
        MsgType       encapSTHdrMsgType
        MsgEncap      encapSTHdrMsgEncap
        MsgHdrVersion uint16
        Msgflag       uint16
        Msglen        uint32
    }

    // Make a buffer to hold header data.
    headerBuf := make([]byte, 12)

    // Read the incoming header info into the buffer.
    _, err := conn.Read(headerBuf)
    if err != nil {
        log.Debug("Error reading:", err.Error())
    }

    // Header is in big endian
    var header encapSTHdr
    headerReader := bytes.NewReader(headerBuf)
    err = binary.Read(headerReader, binary.BigEndian, &header)
    if err != nil {
        log.Debugf("Could not read header bytes into the buffer: %v", err)
    }

    messageBuf := make([]byte, header.Msglen)
    messageBufLen, err := conn.Read(messageBuf)
    if err != nil {
        log.Debugf("Error reading messages: %s", err.Error())
    }
    log.Debugf("The message buffer length is: %d", messageBufLen)
    log.Debugf("The header message length is: %d", header.Msglen) 
}

When I try reading the remaining bytes by making a new buffer of the desired length of 1607, I get a new byte array with data but it is only of length 1228. Hence, I have two questions:

1) Why does conn.Read()not read the remaining bytes?

2) Now I am aware I can use a for loop until I have read the desired amount of bytes and break when done but I was wondering if there was a better way to do this?

  • 写回答

1条回答 默认 最新

  • dqblm40280 2018-09-26 22:17
    关注

    Read returns when data is available, not when it fills the buffer. Use io.ReadFull() to read until the buffer is full or there's an error reading from the connection.

    _, err := io.ReadFull(conn, headerBuf)
    
    ...
    
    _, err := io.ReadFull(conn, messageBuf)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来