perlsocketstcptcpservertcpsocket

How to set in PERL recv timeout in my code?


I want to set timeout in my recv function in this specific code below, because sometimes my script stuck forever. I am new in socket programming so i would really appreciate any help. Thanks in advance.

use IO::Socket::INET;
use IO::Select;
use LWP::UserAgent;
use JSON::XS 'decode_json';
use Data::Dumper;
use DBI();
sub dbconn {
    my $db_conf = shift;

    my $dbh = DBI->connect("DBI:Pg:dbname=somedatabase;host=somehost", "postgres", "",
                                        {pg_server_prepare => 
                                        0,AutoCommit => 1,RaiseError=>1});
    $dbh->do("SET CLIENT_ENCODING TO 'UTF-8';");
    return $dbh;
}



# auto-flush on socket
$| = 1;

# creating a listening socket
my $socket = new IO::Socket::INET (
    LocalHost => '0.0.0.0',
    LocalPort => '5000',
    Proto => 'tcp',
    Listen => 5,
    Reuse => 1
);
die "cannot create socket $!\n" unless $socket;

$sel = IO::Select->new( $socket );

print "Server waiting for client connection on port 5000...\n";

my $command = 1;
my $watchTracker = "*HQ,";
my $tl206 = ",LAT:";
my $watchConnectedCheck = ",A,";
my $gpsType;
my $circleString = ",LINK,";
my $dataToSend;
my $new;
my $dbh = dbconn();
while(@ready = $sel->can_read) {

        foreach $fh (@ready) {
            if($fh == $socket) {
                # Create a new socket
                $new = $socket->accept;



                $new->recv($dataReceived, 1024);
                $new->recv($dataReceived, 1024);




                # get information about a newly connected client
                my $client_address = $new->peerhost();
                my $client_port = $new->peerport();
                print "===============================================\n";
                print "===============================================\n\n";
                print "Connection from $client_address:$client_port\n";

                print "General data received: $dataReceived\n\n";

#MORE LINES...

}
            else {
                # Process socket
                # Maybe we have finished with the socket
                $sel->remove($fh);
                $fh->close;
            }
        }
    }
    $dbh->disconnect();

Solution

  • Perhaps I am misunderstanding the question, but have you tried setting a timeout in the socket with "Timeout"?

    See IO::Socket::INET.

    EDIT: I did not catch the 'recv' bit. You have to use setsockopt, which is not wholly portable, so the final answer is somewhat dependent on your platform. Here are some posts that may help:

    How do I set `SO_RCVTIMEO` on a socket in Perl?

    http://www.perlmonks.org/?node_id=761935

    E.g.,

    $socket->setsockopt(SOL_SOCKET, SO_RCVTIMEO, pack('l!l!', 30, 0))
        or die "setsockopt: $!";