aaronwroblewski has asked for the wisdom of the Perl Monks concerning the following question:
Hi, I have only been with Perl for a little over a year and find it to be an extremely useful and powerful language.
I have recently been developing on a network product (client)that requires a server connection to place data into a database.
I figured perl would be a great solution to my requirement and thought I'd give IO::Socket a go.
My server would have to handle multiple simultaneous connections and keep the socket open for what could be an infinite amount of time to receive strings from the client and only close the connection when it is lost or closed by the client.
I managed to get it all running and it seems to run extremely well, UNTIL:
After running for several hours, half a day or so, and receiving and processing data. the program becomes unresponsive. The sever still accepts connections on the listening port however does not do anything, no response.
If I stop and start the script however it continues to function as usual until it hangs again.
Please help, what am i doing wrong.
Here is my script, sorry for the lack of commenting.
#!/usr/bin/perl use IO::Socket; use IO::Handle; use DBI; $sqlhost ="localhost"; $sqluser ="sqluser"; $sqlpass ="sqlpass"; $sqldb ="sqldb"; $sqltbl ="sqltable"; use Sys::Hostname; use POSIX qw(:sys_wait_h); sub REAP { 1 until (-1 == waitpid(-1, WNOHANG)); $SIG{CHLD} = \&REAP; } $SIG{CHLD} = \&REAP; while (1){ my $sock = new IO::Socket::INET ( LocalHost => 'localhost', LocalPort => '1818', Proto => 'tcp', Listen => 255, Reuse => 1, Timeout => '15',); $sock or die "no socket :$!"; STDOUT->autoflush(1); my($new_sock, $buf, $kid); while ($new_sock = $sock->accept()) { $new_sock->autoflush(1); # execute a fork, if this is # the parent, its work is done, # go straight to continue next if $kid = fork; die "fork: $!" unless defined $kid; # child now... # close the server - not needed close $sock ; while (defined($buf = <$new_sock>)) { chop $buf; foreach ($buf) { $socketport=$new_sock->sockport(); $socketaddress=$new_sock->sockaddr(); $peerip=$new_sock->peerhost(); $peerport=$new_sock->peerport(); print "\n\n\nAccepted New Client Connection From : $peerip:$pe +erport\n "; print "Socket Created On : $sockeaddress:$socketport\n\n"; print "Client Said \" $_ \"\n"; # Pull String apart and do stuff! $scount=substr($_,16,1); $msgtype=substr($_,1,2); $msgseq=substr($_,3,1); $msgreply=substr($_,1,3); $alarm=substr($_,49,1); $data="!$msgreply\OK"; $alarmreset="!DA".$msgseq."5555"; # Reply Client print $new_sock "$data\r\n"; print "I Said \"$data\"\r\n"; if($scount=~/A/){ $from=substr($_,4,6); $hours=substr($_,10,2); $mins=substr($_,12,2); $secs=substr($_,14,2); $latd=substr($_,17,2); $latm= substr($_,19,6)/10000; $late=substr($_,25,1); $longd=substr($_,26,3); $longm=substr($_,29,6)/10000; $longe=substr($_,35,1); $d=$latd; $m=$latm/60; $latituded=$d+$m; $dd=$longd; $mm=$longm/60; $longituded=$dd+$mm; if($late=~/S/){ $latituded="-$latituded"; }; if($longe=~/W/){ $longituded="-$longituded"; }; $knots=substr($_,36,3); $kph=($knots * 1.852); $mph=($knots * 1.150779); $azmth=substr($_,39,3); $day=substr($_,42,2); $month=substr($_,44,2); $year=substr($_,46,2); $epanic=($_,49,1); $eoverspeed=($_,52,1); $egeoin=($_,52,1); $egeoout=($_,52,1); $egeooutspeed=($_,52,1); $egeoinspeed=($_,52,1); $event=substr($_,48,5); if ($epanic =~ /D/){ $panic = "-1"; } else { $panic="0"; } if ($eoverspeed =~ /D/){ $overspeed = "-1"; } else { $overspeed="0"; } if ($egeoin =~ /B/){ $geoin = "-1"; } else { $geoin="0"; } if ($egeoout =~ /A/){ $geoout = "-1"; } else { $geoout="0"; } if ($egeooutspeed =~ /E/){ $geooutspeed = "-1"; } else { $geooutspeed="0"; } if ($egeoinspeed =~ /F/){ $geoinspeed = "-1"; } else { $geoinspeed="0"; } # Send Proccessed String to Database! $dbh = DBI->connect("dbi:mysql:$sqldb;host=$sqlhost", $sqluser , $sqlp +ass); $sql = "INSERT INTO `$sqldb`.`$sqltbl` ( `peerip` , `peerport` , `selfrom` , `longdeg` , `longmin` , `longcomp` , `latdeg` , `latmin` , `latcomp` , `longdec` , `latdec`, `hours` , `mins` , `secs` , `knots` , `kph` , `mph` , `azimuth` , `day` , `month` , `year` , `event`, `panic`, `overspeed`, `geoin`, `geoout`, `geooutspeed`, `geoinspeed` ) VALUES ( '$peerip' , '$peerport' , '$from' , '$longd', '$longm', '$longe', '$latd', '$latm', '$late', '$longituded', '$latituded', '$hours', '$mins', '$secs', '$knots', '$kph', '$mph', '$azmth', '$day', '$month', '$year', '$event', '$panic', '$overspeed', '$geoin', '$geoout', '$geooutspeed', '$geoinspeed' ); "; $sth = $dbh->prepare($sql); $sth->execute; $dbh->disconnect; }; $new_sock->flush; } } exit; } continue { # parent closes the client since # it is not needed close $new_sock; } close($new_sock); }
|
|---|