ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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.
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.
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;
}
}
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.
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 ?
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...
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.
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.