Я пытаюсь эмулировать некоторые небольшие части API-интерфейса HTTP (для проверки некоторых сценариев - сценарии предназначены для запуска с некоторым программным обеспечением, реализующим полный API, но сделать так, чтобы он запускался и передавал исходные данные для тестирования, сложно).
Пока у меня есть небольшой Perl-скрипт, использующий IO :: Socket :: INET для прослушивания TCP-соединений, который отлично работает для эмуляции GET-запросов, но мне также приходится обрабатывать некоторые POST-запросы, и для этого яЯ немного застрял.Я очень хорошо читаю заголовки и нахожу, например, «Content-Length: 20», но затем мне нужно прочитать те 20 байтов, которые часто не заканчиваются переводом строки.
Я пробовал
$client_socket->recv($data, $content_length);
и
sysread $client_socket, $data, $content_length;
, но оба возвращаются, только когда получают EOL (я не проверял, нужны ли им \n
, \r
или оба, поскольку это не имеет значения), но затем возвращает только то количество байтов, которое я запросил.
Я, вероятно, не искал правильных слов, все, что я нашел, это то, что время ожидания можно установить на IO :: Socket ::INET используется только для соединения, и если я использую IO :: Socket :: Timeout или оборачиваю чтение в eval-блок с тревогой, ничего не читается.
Поскольку комментарии показали, чточто-то еще происходило, я копался.Кажется, $socket->recv
меняет поведение, если я ранее читал из сокета с $data = <$socket>
, например (не полный сценарий - я не думаю, что это интересно, но если кто-то хочет один, я могу предоставить один):
$client_socket->recv($data, 4);
print "1: $data\n";
$data = <$client_socket>;
print "2: $data\n";
$client_socket->recv($data, 4);
print "3: $data\n";
Это выводит строки только с 1:
и 2:
, когда в сокет отправляется несколько строк (я просто использовал curl
для генерации нескольких (я думаю) строк данных).