Perl client socket - >recv() Vs когда серверный сокет вызывает send несколько раз
У меня есть серверный сокет perl, который возвращает поля по одному, вызывая send () на клиентском сокете.
У меня нет проблем с чтением всех полей на стороне клиента, если код выглядит следующим образом:
while ($response = <$sock>) {
print "$response";
last if $response eq "END_OF_REQUEST";
}
Но если код на стороне клиента похож на приведенный ниже, он входит в цикл и не работает:
while(1) {
$sock->recv($response, 1);
print "$responsen";
last if $response eq "END_OF_REQUEST" ;
}
Я согласен, что могу объединить все поля и вызвать только один send на стороне сервера. Но мне интересно знать, что не так со 2-м подходом. Не меняется длина arg recv во 2-м подходе делает трюк?
Я вроде как начал получать практический опыт непосредственно без должных теоретических знаний о розетках. Спасибо за ваше терпение.
1 ответ:
Аргумент length для
Таким образом, вашrecv()
- этомаксимальная длина сообщения, которое вы хотите получить, иrecv()
никогда не запишет в буфер больше, чем это количество символов. (То, что происходит с остальной частью сообщения, зависит от типа сокета; для потоковых сокетов он будет доступен для следующего вызоваrecv()
, в то время как для сокетов дейтаграмм он просто выбрасывается.)$sock->recv($response, 1);
запишет в$response
не более одного символа. Очевидно, что односимвольная строка может никогда не равны"END_OF_REQUEST"
. Простое решение состоит в том, чтобы передать достаточно большую максимальную длину вrecv()
, чтобы ваше сообщение не было усечено.
Вот простая демонстрация:
use strict; use warnings; use IO::Socket; my ($rd, $wr) = IO::Socket->socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC) or die "socketpair: $!"; defined $wr->send("Hello, world!") or die "send: $!"; my $buf; do { defined $rd->recv($buf, 9) or die "recv: $!"; print qq(received: "$buf"\n); } while ($buf !~ /!/);
Это выведет:
received: "Hello, wo" received: "rld!"