PDA

View Full Version : Checking Socket Connection


^tasark^
09-12-2002, 10:27 PM
A friend of mine wrote this script us and it's suppose to check the connect to a server, and if it doesn't get a connection (to a certain port for a game) then start the game up by startuping the file. While this will work perfectly if running too long perhaps, I haven't been able to find the pattern yet, but after a while, I type ps -ux in the shell and there will be about 100 start.pl files running and startup files running. And this creates a lot of logs and causes the system admin to not be very happy. So here's what I have. Is something wrong with it? (I use a crontab to start this file every 5 minutes)

#!/usr/bin/perl
$server = "darkened-realms.com";
$port = "7000";
$replyString = "^\n";
$timeOut = "60";
$exec = "/home/tasark/dr/src/startup";
$logdir = "/home/tasark/dr/log";
$startPath = "/home/tasark/dr/src";

use Socket;
require 5.003;

if (&connect_server == 0)
{
print ("Connection to $server on port $port failed or timed out after $timeOut seconds!\n");
$time = (scalar localtime);
print ("Attempting to restart the mud on $time...\n");
&restart_mud;
}
else
{
$readline = (&gl);
if ($readline =~ /$replyString/)
{
&disconnect_server;
exit 1;
}
&disconnect_server;
print ("The connection was sucessful, but it doesn't seem to be responding\n");
$time = (scalar localtime);
print ("Attempting to restart the mud on $time...\n");
system("killall $exec");
&restart_mud;
}

sub connect_server {
my ($iaddr, $paddr, $proto);
$iaddr = inet_aton ($server)
or die ("ERROR: No host: $server!\n");
$paddr = sockaddr_in ($port, $iaddr);
$proto = getprotobyname('tcp');
socket (SOCK, PF_INET, SOCK_STREAM, $proto)
or die ("ERROR: Socket error $!\n");
alarm ($timeOut);
if (connect (SOCK, $paddr)) {;
alarm (0);
return 1;
}
else {
return 0;
}
}

sub disconnect_server {
close (SOCK);
return;
}

sub sl {
my ($line)=@_;
print SOCK ("$line")
or die ("ERROR: Error writing to server: $!\n");
select SOCK;
$|=1;
select STDOUT;
$|=1;
return;
}

sub gl {
my ($buffer, @reply);
$buffer=(<SOCK>);
return ($buffer);
}

sub restart_mud {
$timet = time();
chdir $startPath;
system ("/home/tasark/dr/src/startup &");
return;
}

kmj
09-12-2002, 11:12 PM
please wrap your code int "code" tags, [ code ] and [ /code ] , to preserve proper indentation.. Perl code is messy enough as is, ;)

nex
09-13-2002, 02:15 AM
there's plenty wrong with it.. but as for your problem:

i would imagine that if the mud gets caught in an infinite loop somewhere, it won't accept() connections, and the start.pl will happily spawn another startup script. The startup script will try to boot up the mud, and the mud will exit() after being unable to bind() on the right port. the startup script will probably then sleep for a little bit and try again. 5 minutes later, the start.pl launches another startup. and so on.

I would think the solution is to move the killall part into the restart_mud function, and add a line to kill the mud too.

I assume the entire purpose of this thing is in case the mud hangs; the startup script should take care of anything else. It can't rightly take care of a hung-up mud unless it actually kills the mud.