Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

IO::Socket::INET->getline() function

by akagrawal3 (Beadle)
on Apr 27, 2012 at 09:13 UTC ( #967561=perlquestion: print w/replies, xml ) Need Help??
akagrawal3 has asked for the wisdom of the Perl Monks concerning the following question:

Greetings Monks, I would like to seek your help in a doubt I have. In the below code, @hosts stores the details of devices like RTR, HUB etc which it tries to connect to. When I say devices I mean 'n' number of devices. I try to connect to all of these devices by forking and writing a query which is in XML through $socket->print($query); when
while (my $line = $socket->getline() ) { chomp $line; print {$file_handle} $line; }
is in execution, I believe that the getline() function reads the result which the device writes on its write end. Now my point of concern is for how long will the function getline() wait. I mean that the device may take time in processing the query and writing to the write end. Also what if the device never writes anything to its write end. I am not able to find exactly where this getline() function is defined or explained. Kindly help :)
foreach my $child (@hosts) { my $ident = $child->ident(); my $pid = fork; if ( !$pid ) { my $socket = IO::Socket::INET->new( PeerAddr => $child->get_ip(), PeerPort => $child->get_port(), Proto => 'tcp', Timeout => $child->get_timeout(), ); my @returned_lines; ## no critic(RequireBriefOpen) open my $file_handle, q{>}, CCI::data_path() . $reque +st->get_session_id() . q{/} . $child->get_ip() . '.log'; if ( !$socket ) { $request->error( sprintf 'Unable to connect to %s +: %s', $child->get_ip(), $! ); $returned_lines[0] = sprintf 'ERROR Unable to co +nnect to %s E RROR',$child->get_ip(); print {$file_handle} join q{}, @returned_lines or $request->error('Cannot print to per LGP f +ile'); CORE::exit 0; } $query = $parser->parse_string($query)->toString(1); $socket->print($query); while (my $line = $socket->getline() ) { chomp $line; print {$file_handle} $line; } close $file_handle; # use critic #print {$parent_handle} join q{}, @returned_lines # or $request->error('Cannot return values through + pipe'); CORE::exit 0; } else { push @children, $pid; } }

Replies are listed 'Best First'.
Re: IO::Socket::INET->getline() function
by zentara (Archbishop) on Apr 27, 2012 at 10:39 UTC
    how long will the function getline() wait.

    I'm guessing it will wait until a newline character is sent, or the sending socket closes. Setting an alarm on it might be possible, or an IO::Select timeout. Using sysread is a workaround, but then you need to reassemble the lines at the receiving end.

    See stackoverflow discussion of getline()

    The method getline() and getlines() are in perldoc IO::Handle.

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
      Though getline() function gets one line at a time, I believe that it will wait until the write end of the socket is closed and read end is ready. Socket here I mean of the device. But if device does not close the write end and does not open the read end, say bcos the device goes down just before it tries to close the write end, then will this piece of code keep waiting, since it has already established connection to it and is waiting for reading from the read end of the socket of the device???
        Yes, as confusing as you made it sound, you are on the right track. It seems obvious once you understand the problem of what waiting for a newline does, but just think about it. How does the receive end know when a line is finished? A line can be longer than 80 characters.... it could be a million characters, (or even more) all on the same line. So the receive end has to wait until it sees a newline, so it knows the line ended. Sockets are bi-directional, but do allow for just 1 way transfer. If you get into the recv and send methods, you will see you need to have a protocol, like the "over and back to you" in radio communication. So you can block the socket with recv too, because you tell it to wait until it receives x amount. Google for perl non blocking sockets and you will see the various ways you can get around this problem. Sysread the socket is usually the best way, and use IO::Select. There are plenty of examples on google already.

        It only takes a little bit of logic to sysread the socket for lines. Probably an input storage buffer.

        I'm not really a human, but I play one on earth.
        Old Perl Programmer Haiku ................... flash japh

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://967561]
Approved by marto
and not a whimper to be heard...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (7)
As of 2018-05-23 11:55 GMT
Find Nodes?
    Voting Booth?