LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Detect If A Host Is Alive??? (https://www.linuxquestions.org/questions/programming-9/detect-if-a-host-is-alive-659191/)

murahman 07-30-2008 02:30 AM

Detect If A Host Is Alive???
 
Hello Guys,
I want to make a client server program in perl. The main challange is:
=> before sending any data to server the client will check whethere the server is alive. If server is alive and connected then client will send data.

Please give me an example if possible

Cheers
MISHU

matthewg42 07-30-2008 02:32 AM

You could call ping using system().

murahman 07-30-2008 02:41 AM

Can You Pls Give Me An Example

Cheers

Mr. C. 07-30-2008 02:46 AM

If you are going to write a client/server program, in perl, or any language, you're going to have to learn to read some documentation.

Start with either:

man perldoc
perldoc perldoc

perldoc perlfunc and search system.

Please don't ask others to do the work for you.

murahman 07-30-2008 02:55 AM

Quote:

Originally Posted by Mr. C. (Post 3230643)
If you are going to write a client/server program, in perl, or any language, you're going to have to learn to read some documentation.

Start with either:

man perldoc
perldoc perldoc

perldoc perlfunc and search system.

Please don't ask others to do the work for you.

Guys
Dont get me wrong. I have tried with ping. Its no success. I tried with connect() and socket(). It worked for me to get the status of the server but I was not being able to send any data to server. In the client I am using IO::Socket to send.


Cheers

Mr. C. 07-30-2008 03:04 AM

We can't help if a) you don't tell us what you've tried, what works, what doesn't, and b) you don't share the actual results of your tests (and not mangle results into 'it doesn't work"). There was not a hint that you've tried these things, so it wastes people's time.

You asked how to detect if a host is alive. You got an answer which was to use ping. But you said you can't get it to work.

Now you're asking how to send and receive data. Perhpas getting ping to work should be your first step.

murahman 07-30-2008 03:39 AM

Quote:

Originally Posted by Mr. C. (Post 3230660)
We can't help if a) you don't tell us what you've tried, what works, what doesn't, and b) you don't share the actual results of your tests (and not mangle results into 'it doesn't work"). There was not a hint that you've tried these things, so it wastes people's time.

You asked how to detect if a host is alive. You got an answer which was to use ping. But you said you can't get it to work.

Now you're asking how to send and receive data. Perhpas getting ping to work should be your first step.


This is the code that I have tried so far

my $sendSock = new IO::Socket::INET(PeerPort=> 2345, Proto=> 'tcp', PeerHost=> '120.50.8.8');
my $status;
while(1)
{
$pid = fork();
if($pid == 0)
{
$status = &checkConnectionStatus("120.50.8.8", "2345");
if($status eq 0)
{
$sendSock->send("Hello"); #Cannot send!!!
}
else
{
close($sendSock);
undef($sendSock);
my $sendSock = new IO::Socket::INET(PeerPort=> 2345, Proto=> 'tcp', PeerHost=> '120.50.8.8');
$sendSock->send("Hello");
}
kill($pid);
exit 0;
}
waitpid(-1,1);
sleep(3);
}
sub checkConnectionStatus
{
my $hostname = @_[0];
my $portnumber = @_[1];
my $host = shift || $hostname;
my $port = shift || $portnumber;
my $proto = getprotobyname('tcp');
my $iaddr = inet_aton($host);
my $paddr = sockaddr_in($port, $iaddr);
socket(SOCKET, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
eval
{
local $SIG{ALRM} = sub { die "timeout" };
alarm($timeout);
connect(SOCKET, $paddr) || error();
alarm(0);
};
if ($@)
{
close SOCKET || die "close: $!";
print "$hostname is NOT listening on tcp port $portnumber.\n";
return 1;
}
else
{
close SOCKET || die "close: $!";
print "$hostname is listening on tcp port $portnumber.\n";
return 0;
}
}
sub pingForStatus
{
$hostIP = @_[0];
$hostPort = @_[1];
$p = Net::Ping->new("icmp", 2);
unless ($p->ping($hostIP))
{
print "Fail: \n";
return 0;
}
else
{ print "Success: ";
return 1;
}
}

cheers

murahman 07-30-2008 03:53 AM

The problem is when for the first time the server is on and the client starts then everything works fine. But if i turn off the server at some point and start it again then the server can't receive any data.

thanks

wget 07-30-2008 05:06 AM

Don't no perl but just a hunch. You stop and starting the server, maybe the port that the server wants to use is still in a waiting state, is there a solinger option you can set in perl ?

Just a hunch mind ya.

chrism01 07-30-2008 05:06 AM

some notes:

1. don't use '&' when calling a sub unless you mean a ref to a sub (and you don't here). That's old school (Perl v4).
2. When collecting input vars to a sub, don't mix array & scalar notation. Replace

my $hostname = @_[0];
my $portnumber = @_[1];
my $host = shift || $hostname;
my $port = shift || $portnumber;

with


my $host = $_[0];
my $port = $_[1];

3. don't mix use of IO::Socket module with bare socket creation. Stick to the module.

4. what you need is a retry mechanism like this:

Code:

#******************************************************************************
#
# Function      : create_sending_socket
#
# Description  : Attempt to create sending socket: retry (create) 3 times,
#                then give up.
#
# Params        : none
#
# Returns      : none
#
#******************************************************************************
sub create_sending_socket
{
    my (
        $socket_errmsg,    # msg if socket create failed
        $log_error_msg,    # complete error msg
        $retry              # socket create retry counter
        );

    # If socket connection does not exist & socket retry cnt < 3,
    # then try to create new socket
    $retry = 0;
    while( !$cfg::send_socket && $retry < 3 )
    {
        $socket_errmsg = "";
        $socket_errmsg = get_sending_socket();
        $retry++;
    }

    # Did we succeed ?
    if( $socket_errmsg )
    {
        $log_error_msg = "Failed to connect to send socket in $retry ".
                                                "tries: $socket_errmsg";
        print "$log_error_msg\n";
        send_email($log_error_msg);
    }
}
#******************************************************************************
#
# Function      : get_sending_socket
#
# Description  : Create a socket (INET/TCP type) to send msgs/packets
#                to the radius_packet_sender.pl server.
#                If send socket does not yet exist (see sub hdr above),
#                or connection has gone down, build a new connection socket
#
# Params        : none
#
# Returns      : $socket_errmsg    # error msg if socket not created
#
#******************************************************************************
sub get_sending_socket
{
    my (
        $server,        # FQDN of remote radius server
        $port,          # port to connect on
        $socket_errmsg  # error msg if socket not created
        );

    # Assign params
    $server = $cfg::params{'RPS_SERVER'};
    $port = $cfg::params{'RPS_PORT'};
    if( !$cfg::send_socket )
    {
        # Create socket
        $socket_errmsg = "";
        $cfg::send_socket = IO::Socket::INET->new( PeerAddr => $server,
                                                  PeerPort => $port,
                                                  Proto    => "tcp"
                                                    )
                    or $socket_errmsg =
                        "Couldn't create socket to $server port $port: $@";

        if( !$socket_errmsg )
        {
# DEBUG
print  "get_sending_socket() Success\n";
        }
    }

    # Return socket msg for retry if needed
    return($socket_errmsg);
}

Enclose your code in code tags so it indents properly. Its hard to read as is...

murahman 07-30-2008 06:22 AM

Quote:

Originally Posted by chrism01 (Post 3230747)
some notes:

1. don't use '&' when calling a sub unless you mean a ref to a sub (and you don't here). That's old school (Perl v4).
2. When collecting input vars to a sub, don't mix array & scalar notation. Replace

my $hostname = @_[0];
my $portnumber = @_[1];
my $host = shift || $hostname;
my $port = shift || $portnumber;

with


my $host = $_[0];
my $port = $_[1];

3. don't mix use of IO::Socket module with bare socket creation. Stick to the module.

4. what you need is a retry mechanism like this:

Code:

#******************************************************************************
#
# Function      : create_sending_socket
#
# Description  : Attempt to create sending socket: retry (create) 3 times,
#                then give up.
#
# Params        : none
#
# Returns      : none
#
#******************************************************************************
sub create_sending_socket
{
    my (
        $socket_errmsg,    # msg if socket create failed
        $log_error_msg,    # complete error msg
        $retry              # socket create retry counter
        );

    # If socket connection does not exist & socket retry cnt < 3,
    # then try to create new socket
    $retry = 0;
    while( !$cfg::send_socket && $retry < 3 )
    {
        $socket_errmsg = "";
        $socket_errmsg = get_sending_socket();
        $retry++;
    }

    # Did we succeed ?
    if( $socket_errmsg )
    {
        $log_error_msg = "Failed to connect to send socket in $retry ".
                                                "tries: $socket_errmsg";
        print "$log_error_msg\n";
        send_email($log_error_msg);
    }
}
#******************************************************************************
#
# Function      : get_sending_socket
#
# Description  : Create a socket (INET/TCP type) to send msgs/packets
#                to the radius_packet_sender.pl server.
#                If send socket does not yet exist (see sub hdr above),
#                or connection has gone down, build a new connection socket
#
# Params        : none
#
# Returns      : $socket_errmsg    # error msg if socket not created
#
#******************************************************************************
sub get_sending_socket
{
    my (
        $server,        # FQDN of remote radius server
        $port,          # port to connect on
        $socket_errmsg  # error msg if socket not created
        );

    # Assign params
    $server = $cfg::params{'RPS_SERVER'};
    $port = $cfg::params{'RPS_PORT'};
    if( !$cfg::send_socket )
    {
        # Create socket
        $socket_errmsg = "";
        $cfg::send_socket = IO::Socket::INET->new( PeerAddr => $server,
                                                  PeerPort => $port,
                                                  Proto    => "tcp"
                                                    )
                    or $socket_errmsg =
                        "Couldn't create socket to $server port $port: $@";

        if( !$socket_errmsg )
        {
# DEBUG
print  "get_sending_socket() Success\n";
        }
    }

    # Return socket msg for retry if needed
    return($socket_errmsg);
}

Enclose your code in code tags so it indents properly. Its hard to read as is...

Dear Chris,
your code is wonderful. It works great. But still the same problem. For the first time when both server and client is connected it works fine. But if at some point in the middle of sending the server disconnects and reconnects again it does not get any input. It may be because the previous socket created in client is still being used. For example if the socket name is : $send_socket then !$send_socket cannnot detect whether the connection is the previous one or a new one.

Mind my english Pls

Cheers

murahman 07-30-2008 06:28 AM

Dear Chris,
This is how I have integrated your code with mine. Please help me if i am doing something wrong.


our $status;
our $send_socket;
while(1)
{
$status = create_sending_socket();

if($status eq 1)
{
print "OKKKKK\n";
}
else
{
print "NOT OK \n";
}
sleep(2);
}

sub create_sending_socket
{
my (
$socket_errmsg, # msg if socket create failed
$log_error_msg, # complete error msg
$retry # socket create retry counter
);
# If socket connection does not exist & socket retry cnt < 3,
# then try to create new socket
$retry = 0;
while( !$send_socket && $retry < 3 )
{
$socket_errmsg = "";
$socket_errmsg = get_sending_socket();
$retry++;
}
# Did we succeed ?
if( $socket_errmsg )
{
return 0;
}
else
{
return 1;
}
}
sub get_sending_socket
{
my (
$server, # FQDN of remote radius server
$port, # port to connect on
$socket_errmsg # error msg if socket not created
);

# Assign params
$server = "120.50.8.8";
$port = "2345";
if( !$send_socket )
{
# Create socket
$socket_errmsg = "";
$send_socket = IO::Socket::INET->new( PeerAddr => $server,
PeerPort => $port,
Proto => "tcp"
)
or $socket_errmsg = "Couldn't create socket to $server port $port: $@";
if( !$socket_errmsg )
{
# DEBUG
print "get_sending_socket() Success\n";
}
}
# Return socket msg for retry if needed
return($socket_errmsg);
}

Thanks Buddy

chrism01 07-30-2008 07:53 AM

I don't want to write the whole code for you, so here's some tips:

1. use code tags(!), its very difficult to read your stuff
2. when you send a msg to the server from the client, you need to check that it succeeded. If it didn't, close and clear the socket var and start over.

murahman 07-30-2008 08:06 AM

Code:

#!/usr/bin/perl

use DBI;
use Convert::EBCDIC;

use HTTP::Date;
my ($date, $time) = split(" ", HTTP::Date::time2iso());
my ($hour, $min) = split(":", $time);


#use strict;
use IO::Socket;
use Time::Local;
use Net::Ping;

$SIG{CHLD} = sub { wait()};
my $sock = new IO::Socket::INET(
                  LocalHost => '120.50.8.8',
                  LocalPort => 1234,
                  Proto    => 'tcp',
                  Listen    => SOMAXCONN,
                  Reuse    => 1);
                 
#my $sendSock = new IO::Socket::INET(PeerPort=> 2345, Proto=> 'tcp', PeerHost=> '120.50.8.8', Reuse=> 1);

our $status;
our $send_socket; #declared this as global is this alright??
while(1)
{
  $status = create_sending_socket();
 
  if($status eq 1)
  {
      print "OKKKKK\n";
  }
  else
  {
      print "NOT OK \n";
  }
 
  sleep(2);
}

sub create_sending_socket
{
    my (
        $socket_errmsg,    # msg if socket create failed
        $log_error_msg,    # complete error msg
        $retry              # socket create retry counter
        );

    # If socket connection does not exist & socket retry cnt < 3,
    # then try to create new socket
    $retry = 0;
    while( !$send_socket && $retry < 3 ) # this cannot detect whethere connections broken or not
    {
        $socket_errmsg = "";
        $socket_errmsg = get_sending_socket();
        $retry++;
    }

    # Did we succeed ?
    if( $socket_errmsg )
    {
        return 0;
    }
    else
    {
      return 1;
    }
}

sub get_sending_socket
{
    my (
        $server,        # FQDN of remote radius server
        $port,          # port to connect on
        $socket_errmsg  # error msg if socket not created
        );

    # Assign params
    $server = "120.50.8.8";
    $port = "2345";
    if( !$send_socket ) # this cannot determin if conn is open or not
    {
        # Create socket
        $socket_errmsg = "";
        $send_socket = IO::Socket::INET->new( PeerAddr => $server,
                                                  PeerPort => $port,
                                                  Proto    => "tcp"
                                                    )
                    or $socket_errmsg = "Couldn't create socket to $server port $port: $@";

        if( !$socket_errmsg )
        {
          # DEBUG
            print  "get_sending_socket() Success\n";
        }
    }

    # Return socket msg for retry if needed
    return($socket_errmsg);
}

Is this alright?? I am sorry I am quite new in linuxquestions

Thanks

chrism01 07-30-2008 08:57 PM

This
#!/usr/bin/perl
should be

#!/usr/bin/perl -w

ie uses warnings.

Do NOT disable 'use strict;'

What's that first socket create for? Always check the create as per my example.

Test run your prog (and log the errors if any), I'm not going to try and reproduce everything here to guess if it works for you...


All times are GMT -5. The time now is 02:34 PM.