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?
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)
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With