io.Reader.Read(p []byte)
- в случае успеха - может свободно возвращать любое количество байтов от 1 до len(p)
; это по
его контракт :
Read читает до len(p)
байтов в p
. Возвращает количество прочитанных байтов (0 <= n <= len(p)
) и обнаруженную ошибку. Даже если Read
возвращает n < len(p)
, он может использовать все p как пустое место во время вызова. Если некоторые данные доступны, но не len(p)
байтов, Read
условно возвращает то, что доступно, вместо ожидания большего.
(Акцент мой.)
"Магическое число" 4096, которое вы наблюдаете, вероятно, является размером кеша некоторого программного обеспечения под вашим TLS-соединением.
Это фактически соответствует договору системного вызова POSIX read(2)
(для сокетов это на самом деле будет recv(2)
- от «сокетов BSD», которые реализует каждая платформа, поддерживаемая Go, включая Windows; его аналог из Winsock имеет ту же семантику, FWIW ).
Если вы точно знаете , сколько байтов нужно прочитать из источника, используйте помощник io.ReadFull
.
Обычно это самый простой подход к работе с данными.
закодирован в формате TLV (и encoding/binary
также помогает).