Является ли ваш сокет TCP или UDP?
recv
- это процедура более низкого уровня, чем <>
/ readline
.Он более или менее отображается непосредственно на системный вызов recv(2)
.Если данные сокета поступают в виде 4 4-байтовых пакетов, recv
немедленно вернется, как только увидит первый пакет, даже если ему был предоставлен больший буфер.Если все 4 пакета прибывают до первого вызова recv()
, то, получите ли вы все данные или только один фрагмент, зависит от того, будет ли это TCP или UDP.
Если вы используете TCP, есть вероятностьэти пакеты будут фрагментированы в полете.Это вряд ли произойдет с 16-байтовыми полезными нагрузками, но лучше не предполагать, что 16 байтов данных будут отображаться одновременно, даже если вы знаете, что сервер отправил их все сразу.Обычно сетевые приложения должны буферизовать входящие данные, или вы можете сделать это для perl, указав 16-байтовые записи с $/ = \16
.
Еще одна возможность, которую я считаю более естественной, чем <>
для этого вида использования ввода / вывода следует использовать функции read
или sysread
(или эквиваленты OO, которые определены в IO::Socket
суперклассе IO::Handle
).Они принимают аргумент длины, но, как и прежде, не следует предполагать, что весь буфер будет заполнен сразу.