Perl client socket-> recv () Vs <> when calling server socket multiple times

I have a third party perl server that returns fields one by one, calling send () on the client socket.

I have no problem reading all fields on the client side as long as the code looks like this:

while ($response = <$sock>) {
print "$response";
last if $response eq "END_OF_REQUEST";
}

      

But if the client side code looks like below, it goes into a loop and doesn't work:

while(1) {      
$sock->recv($response, 1);
print "$response\n";    
last if $response eq "END_OF_REQUEST" ;
}

      

I agree that I can concatenate all fields and only cause one server side dispatch. But I'm interested in figuring out what is wrong with the second approach. Does LENGTH change the recv argument in the second approach?

I kind of started practicing straight without proper theoretical knowledge of sockets. Thank you for your patience.

+3


source share


1 answer


The length argument to recv()

is the maximum length of the message you want to receive, and recv()

will never write more than many characters to the buffer. (What happens to the rest of the message depends on the type of socket, for stream sockets it will be available for the next call recv()

, while for datagram sockets it is simply discarded.)

So yours $sock->recv($response, 1);

will write at most one character to $response

. Obviously, a single character string can never be equal "END_OF_REQUEST"

.

The simple solution is to pass a long enough maximum length to recv()

so that your message isn't truncated.




Here's a simple demo:

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 !~ /!/);

      

This will output:

received: "Hello, wo"
received: "rld!"

      

+4


source







All Articles