Как мне продолжить чтение оставшихся байтов после чтения первых нескольких байтов с помощью conn.Read () в Go? - PullRequest
0 голосов
/ 27 сентября 2018

Я пытаюсь прочитать из TCP-соединения в Go.У меня есть определенный формат заголовка, который я пытаюсь проанализировать первым.Итак, прочитайте первые 12 байтов, в которых есть информация, связанная с заголовком.И это говорит мне, что оставшаяся длина сообщения - это определенное количество байтов.В этом случае 1607 байтов.Я попытался следующий код, где я прочитал байты заголовка, а затем попытался прочитать оставшиеся байты.

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) 
}

Когда я пытаюсь прочитать оставшиеся байты, создав новый буфер желаемой длины 1607, яполучить новый байтовый массив с данными, но он имеет длину только 1228. Следовательно, у меня есть два вопроса:

1) Почему conn.Read () не читает оставшиеся байты?

2Теперь я знаю, что могу использовать цикл for, пока не прочту желаемое количество байтов и не прервусь, когда закончу, но мне было интересно, есть ли лучший способ сделать это?

1 Ответ

0 голосов
/ 27 сентября 2018

Read возвращается, когда данные доступны, а не когда они заполняют буфер.Используйте io.ReadFull () для чтения, пока буфер не заполнится или не возникнет ошибка чтения из соединения.

_, err := io.ReadFull(conn, headerBuf)

...

_, err := io.ReadFull(conn, messageBuf)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...