4
\$\begingroup\$

I'm relatively new to Go, which is why I decided to post some code here. My goal is to en-/decode a TCP stream. The individual data packets length-based. The first two bytes are the unsigned size in little-endian byte order. The size includes the size field itself. The methods I wrote seem to en-/decode the packets as expected.

Is there a more efficient way to achieve this? Does Go perhaps already implement such methods somewhere.


func GetPacketByLength(source io.Reader) ([]byte, error) {
    s := make([]byte, 2)
    if _, err := io.ReadFull(source, s); err != nil {
        return nil, err
    }

    // Little-endian uint16
    size := uint16(s[0]) | uint16(s[1])<<8 - 2

    p := make([]byte, size)
    if _, err := io.ReadFull(source, p); err != nil {
        return nil, err
    }

    return p, nil
}

func PutPacketByLength(target io.Writer, p []byte) error {
    s := make([]byte, 2)

    // Little-endian uint16
    s[0] = byte((len(p) + 2))
    s[1] = byte((len(p) + 2) >> 8)

    if _, err := target.Write(s); err != nil {
        return err
    }
    if _, err := target.Write(p); err != nil {
        return err
    }

    return nil
}
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

You may consider to use binary.Read. I find this more readable and self documented. See this example.

var len uint16
err := binary.Read(buf, binary.LittleEndian, &len)

The writing part:

len := uint16(len(p))
err := binary.Write(buf, binary.LittleEndian, len)

Also don't forget to check that len(p) doesn't overflow uint16 (less than 65535).

Apart from that your code is fine.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.