Forum Moderators: coopster & phranque

Message Too Old, No Replies

keeping a listen alive?

port programming

         

mactac

8:44 pm on May 31, 2004 (gmt 0)

10+ Year Member




I have an perl application running that listens on a port & accepts connection. If for some reason it does, obviously there is nothing there to accept port connections anymore

is there a way to keep it going, or restart automatically immediately after it dies?

I know you could setup a cron job, but it would be limited by how often it checks.. (5 mins, etc). is there any way to continually monitor it?

thanks

MichaelBluejay

10:17 pm on May 31, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I think you mean "if for some reason it DIES" rather than "if for some reason it DOES"?

Anyway, why *wouldn't* you use a cron job? Isn't that what they're for?

I can't think of any other way to restart a script, but then again my experience with Perl is pretty much limited to messin' with data.

mactac

10:32 pm on May 31, 2004 (gmt 0)

10+ Year Member



>I think you mean "if for some reason it DIES" rather than "if for some reason it DOES"?

ah yes, indeed :)

well, the problem with a cron is that it would have to run every 5 seconds or something like that, I can't have the script down for even that long....

any other way to do it anyone can think of?

thanks!

MichaelBluejay

1:37 am on Jun 1, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I think the fundamental problem is that if your script dies, it's incapable of informing you of that fact or restarting itself. So it seems you need some outside force to monitor it, and that's what a cron job can do. But whatever is monitoring it, a cron job or another script or something else, if it's checking every second that would probably be a fair hit to your server.

mactac

1:52 am on Jun 1, 2004 (gmt 0)

10+ Year Member



that's exactly my point... is there no other way? this is probably a fairly commen issue, as a LOT of socket stuff is written in perl

VectorJ

3:43 pm on Jun 1, 2004 (gmt 0)

10+ Year Member



The socket operation is pretty stable and shouldn't just spontaneously die. I noticed that you used the word "accept", which implies that you're using the accept method rather than an IO::Select object to poll your socket. Could it be that the socket is blocking while data is being transmitted and not actually dying? If so, you need to create a multiplexing socket with the IO::Select module. Here's some code to use the IO::Select object, if that is indeed the problem:


$server = IO::Socket::INET->new(LocalPort => $server_port,
Type => SOCK_STREAM,
Reuse => 1,
Proto => 'tcp',
Listen => 128 ) ¦¦ die "couldn't be a server: $!\n";

$readable_handles = IO::Select->new();
$readable_handles->add($server);
while (1) {
($new_readable) = IO::Select->select($readable_handles, undef, undef, undef);
foreach $sock (@$new_readable) {
if ($sock == $server) {
$new_sock = $sock->accept();
$readable_handles->add($new_sock);
} else {
$req = <$sock>;
if ($req) {
#do something with the socket
} else {
$readable_handles->remove($sock);
close ($sock);
}
}
}
}


On Linux or BSD I think you can set Listen as high as 1024; as I recall Solaris limits Listen to 5 unless you recompile the kernel.

trillianjedi

3:50 pm on Jun 1, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Are you in control of the client script/app as well as the server?

The usual way of approaching this problem programmatically is to implement a PING procedure (from client to server).

So client sends server a ping byte every few seconds (say Y seconds). If server doesn't receive a ping in a time period of X + Y seconds, then server assumes the TCP/IP binding has dropped and restarts listening again.

There is no other way of detecting a binding drop if the server is not expecting activity (where a timeout would be appropriate). TCP/IP is designed in such a way that connections can go quiet for long periods of time. Setup a local network socket connection and pull the RJ45 out of the back of the client machine once you've established the socket binding and you'll see what I mean.

As others have stated, if you cannot implemnent an interval ping, then you have no option but restart via an outside app.

TJ

mactac

4:14 pm on Jun 1, 2004 (gmt 0)

10+ Year Member



Thanks -

What do you mean by a "multiplexing socket"?

thanks

VectorJ

4:21 pm on Jun 1, 2004 (gmt 0)

10+ Year Member



A regular socket using the accept method accepts a single connection, handles it, closes it, then returns to accept a new connection, the whole time blocking connections to the socket. A multiplexing socket (one that uses the IO::Select module) will accept many connections and handle them without blocking (unless the Listen number is reached, then it will block). So multiplexing just means that the socket will continue to accept connections instead of blocking them, even while it is handling other connections. That's what the IO::Select module allows you to do.

SeanW

1:02 pm on Jun 2, 2004 (gmt 0)

10+ Year Member



If you want a script to always run and restart when it dies, start it up out of /etc/inittab.

However, it's probably better to design your app better. Generally, socket applications listen() for the incoming connection, then fork() a child to accept() the request. The parent process just sits around and waits for connections.

Sean