Home > Archive > PERL Beginners > March 2008 > Client-Server Architecture script
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Client-Server Architecture script
|
|
| Anirban Adhikary 2008-03-17, 7:08 pm |
| Dear List
I want to write a script using TCP protocol where will be a single server
which can handle multiple client request simultaneously. I am able to
write a script using IO::Socket but In these scripts my server can handle
single client suppose my server is printing the IP address of the client
and print 10 times hello world like this............ But that is not the
thing which I want ............. I need a script which will print the IP
address of the client from which it receives the request and also execute
the request which it is receiving from the clients. Regarding this if I get
u people's help I will be highly obliged.
Thanks&Regards in advance
Anirban Adhikary.
| |
| Chas. Owens 2008-03-17, 7:08 pm |
| On Mon, Mar 17, 2008 at 3:02 PM, Anirban Adhikary
<anirban.adhikary@gmail.com> wrote:
> Dear List
> I want to write a script using TCP protocol where will be a single server
> which can handle multiple client request simultaneously. I am able to
> write a script using IO::Socket but In these scripts my server can handle
> single client suppose my server is printing the IP address of the client
> and print 10 times hello world like this............ But that is not the
> thing which I want ............. I need a script which will print the IP
> address of the client from which it receives the request and also execute
> the request which it is receiving from the clients. Regarding this if I get
> u people's help I will be highly obliged.
>
> Thanks&Regards in advance
> Anirban Adhikary.
>
Take a look at IO::Select*.
* http://search.cpan.org/dist/IO/IO/Select.pm
--
Chas. Owens
wonkden.net
The most important skill a programmer can have is the ability to read.
| |
| Zentara 2008-03-18, 7:03 pm |
| On Tue, 18 Mar 2008 00:32:13 +0530, anirban.adhikary@gmail.com ("Anirban
Adhikary") wrote:
>Dear List
>I want to write a script using TCP protocol where will be a single server
>which can handle multiple client request simultaneously. I am able to
>write a script using IO::Socket but In these scripts my server can handle
>single client suppose my server is printing the IP address of the client
>and print 10 times hello world like this............ But that is not the
>thing which I want ............. I need a script which will print the IP
>address of the client from which it receives the request and also execute
>the request which it is receiving from the clients. Regarding this if I get
>u people's help I will be highly obliged.
>
>Thanks&Regards in advance
>Anirban Adhikary.
There are alot of examples on groups.google.com. Search for
"perl multi-echo chat". But these will get you started.
Also http://perlmonks.org?node_id=627553 for some more code.
#server
#!/usr/bin/perl
use IO::Socket;
use IO::Select;
my @sockets;
my $machine_addr = 'localhost';
$main_sock = new IO::Socket::INET(LocalAddr=>$machine_addr,
LocalPort=>12345,
Proto=>'tcp',
Listen=>3,
Reuse=>1,
);
die "Could not connect: $!" unless $main_sock;
print "Starting Server\n";
$readable_handles = new IO::Select();
$readable_handles->add($main_sock);
while (1)
{
($new_readable) = IO::Select->select($readable_handles, undef, undef,
0);
foreach $sock (@$new_readable)
{
if ($sock == $main_sock)
{
$new_sock = $sock->accept();
$readable_handles->add($new_sock);
}
else
{
$buf = <$sock>;
if ($buf)
{
print "$buf\n";
my @sockets = $readable_handles->can_write();
#print $sock "You sent $buf\n";
foreach my $sck(@sockets){print $sck "$buf\n";}
}
else
{
$readable_handles->remove($sock);
close($sock);
}
}
}
}
print "Terminating Server\n";
close $main_sock;
getc();
__END__
#######################################
#client
#!/usr/bin/perl -w
use strict;
use IO::Socket;
my ( $host, $port, $kidpid, $handle, $line );
( $host, $port ) = ('192.168.0.9',1200);
my $name = shift || '';
if($name eq ''){print "What's your name?\n"}
chomp ($name = <> );
# create a tcp connection to the specified host and port
$handle = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => $host,
PeerPort => $port
)
or die "can't connect to port $port on $host: $!";
$handle->autoflush(1); # so output gets there right away
print STDERR "[Connected to $host:$port]\n";
# split the program into two processes, identical twins
die "can't fork: $!" unless defined( $kidpid = fork() );
# the if{} block runs only in the parent process
if ($kidpid) {
# copy the socket to standard output
while ( defined( $line = <$handle> ) ) {
print STDOUT $line;
}
kill( "TERM", $kidpid ); # send SIGTERM to child
}
# the else{} block runs only in the child process
else {
# copy standard input to the socket
while ( defined( $line = <STDIN> ) ) {
print $handle "$name->$line";
}
}
__END__
Remember, IO::Select shares time amoung the sockets. So if
your messages are short, things will work fine. BUT if one client
tries to transfer a huge file, select will block all other clients until
the one client-hog is done. In that case you may need a "forking server"
or a "threaded server".
zentara
--
I'm not really a human, but I play one on earth.
http://zentara.net/japh.html
| |
| Anirban Adhikary 2008-03-18, 7:03 pm |
| Dear List
I have a question regarding this client - server script. I am using two
modules in my script . One is IO::Socket and another is IO::Select. Now my
question is if I want to implement an architecture so that client script
will send a command to the server* [*which doesn't require root privilege to
run ( like ls -l .... ps etc.)* ] *the server script then execute that
command in the server machine and the output will be displayed again at
client's machine console or output will be stored in the client machine's
specified directory. If yes then how? Is it possible to implement such
architecture by using these two modules? If u people know some good
tutorials related with this type of architecture then please let me know. If
I get any example code available related with this architecture from ur side
I will be highly privileged.
Thanks & Regards In Advance
Anirban Adhikary.
On Tue, Mar 18, 2008 at 6:57 PM, zentara <zentara@highstream.net> wrote:
> On Tue, 18 Mar 2008 00:32:13 +0530, anirban.adhikary@gmail.com ("Anirban
> Adhikary") wrote:
>
> get
>
> There are alot of examples on groups.google.com. Search for
> "perl multi-echo chat". But these will get you started.
> Also http://perlmonks.org?node_id=627553 for some more code.
>
>
> #server
> #!/usr/bin/perl
> use IO::Socket;
> use IO::Select;
>
> my @sockets;
> my $machine_addr = 'localhost';
> $main_sock = new IO::Socket::INET(LocalAddr=>$machine_addr,
> LocalPort=>12345,
> Proto=>'tcp',
> Listen=>3,
> Reuse=>1,
> );
>
> die "Could not connect: $!" unless $main_sock;
> print "Starting Server\n";
>
> $readable_handles = new IO::Select();
> $readable_handles->add($main_sock);
>
> while (1)
> {
> ($new_readable) = IO::Select->select($readable_handles, undef, undef,
> 0);
>
> foreach $sock (@$new_readable)
> {
> if ($sock == $main_sock)
> {
> $new_sock = $sock->accept();
> $readable_handles->add($new_sock);
> }
> else
> {
> $buf = <$sock>;
> if ($buf)
> {
> print "$buf\n";
> my @sockets = $readable_handles->can_write();
> #print $sock "You sent $buf\n";
> foreach my $sck(@sockets){print $sck "$buf\n";}
>
> }
> else
> {
> $readable_handles->remove($sock);
> close($sock);
> }
> }
> }
>
> }
>
>
> print "Terminating Server\n";
> close $main_sock;
> getc();
> __END__
>
> #######################################
>
> #client
> #!/usr/bin/perl -w
> use strict;
> use IO::Socket;
>
> my ( $host, $port, $kidpid, $handle, $line );
>
> ( $host, $port ) = ('192.168.0.9',1200);
>
> my $name = shift || '';
> if($name eq ''){print "What's your name?\n"}
> chomp ($name = <> );
>
>
> # create a tcp connection to the specified host and port
> $handle = IO::Socket::INET->new(
> Proto => "tcp",
> PeerAddr => $host,
> PeerPort => $port
> )
> or die "can't connect to port $port on $host: $!";
> $handle->autoflush(1); # so output gets there right away
> print STDERR "[Connected to $host:$port]\n";
>
> # split the program into two processes, identical twins
> die "can't fork: $!" unless defined( $kidpid = fork() );
>
> # the if{} block runs only in the parent process
> if ($kidpid) {
>
> # copy the socket to standard output
> while ( defined( $line = <$handle> ) ) {
> print STDOUT $line;
> }
> kill( "TERM", $kidpid ); # send SIGTERM to child
> }
>
> # the else{} block runs only in the child process
> else {
>
> # copy standard input to the socket
> while ( defined( $line = <STDIN> ) ) {
> print $handle "$name->$line";
> }
> }
> __END__
>
>
> Remember, IO::Select shares time amoung the sockets. So if
> your messages are short, things will work fine. BUT if one client
> tries to transfer a huge file, select will block all other clients until
> the one client-hog is done. In that case you may need a "forking server"
> or a "threaded server".
>
>
> zentara
>
>
>
>
>
> --
> I'm not really a human, but I play one on earth.
> http://zentara.net/japh.html
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe@perl.org
> For additional commands, e-mail: beginners-help@perl.org
> http://learn.perl.org/
>
>
>
| |
| Zentara 2008-03-19, 7:02 pm |
| On Tue, 18 Mar 2008 22:16:28 +0530, anirban.adhikary@gmail.com ("Anirban
Adhikary") wrote:
>I have a question regarding this client - server script. I am using two
>modules in my script . One is IO::Socket and another is IO::Select. Now my
>question is if I want to implement an architecture so that client script
>will send a command to the server* [*which doesn't require root privilege to
>run ( like ls -l .... ps etc.)* ] *the server script then execute that
>command in the server machine and the output will be displayed again at
>client's machine console or output will be stored in the client machine's
>specified directory. If yes then how? Is it possible to implement such
>architecture by using these two modules? If u people know some good
>tutorials related with this type of architecture then please let me know. If
>I get any example code available related with this architecture from ur side
>I will be highly privileged.
>
>Thanks & Regards In Advance
>Anirban Adhikary.
Hi, for a good tutorial about the basics of sockets, see
http://www.cs.uno.edu/~golden/teach.html and look for the
Perl socket examples. He does it from the basic level but explains
what each step does in detail.
Then you can move up from using the basic Sockets and select, to the
easier modules IO::Socket and IO::Select ( which handle many of the
tedious details for you).
For a good example of problems using sockets to send data on demand,
see http://perlmonks.org?node_id=627553
For things like executing remote commands on a server, it is highly
recommended to use ssh instead, for security reasons.
See http://perlmonks.org?node_id=569657 for a demo of how
to use Net::SSH2 which is the starte of the art preferred module now.
It shows how to run system commands like ls.
zentara
--
I'm not really a human, but I play one on earth.
http://zentara.net/japh.html
| |
| Anirban Adhikary 2008-03-20, 4:02 am |
| Dear List
I have able to write the client-server architecture script *( Based on the
script send by ZENTARA )* which can execute command at the server end and
display the result at client end . But the problem I am facing that the
server can not able to support multiple client it is only able to support a
single client. I am also trying to implement when the server script will
stopeed *( Like using ctrl +c)* then all clients will get some message from
server about the connection closing.In the server side when some client get
disconnected from server some message will get priented in the server
console . I am posting my code here U guys pls help me how to solve these
problems.
Thanks & Regards in advance
Anirban Adhikary.
*THE SERVER SCRIPT
*#######################################
##############################
#!/usr/bin/perl
use IO::Socket;
use IO::Select;
my @sockets;
my $machine_addr = '10.5.2.174';
$main_sock = new IO::Socket::INET(LocalAddr=>$machine_addr,
LocalPort=>12000,
Proto=>'tcp',
Listen=>3,
Reuse=>1,
);
die "Could not connect: $!" unless $main_sock;
print "Starting Server\n";
my($new_sock, $c_addr, $buf);
while (($new_sock, $c_addr) = $main_sock->accept())
{
my ($client_port, $c_ip) =
sockaddr_in($c_addr);
my $client_ipnum = inet_ntoa($c_ip);
my $client_host =
gethostbyaddr($c_ip, AF_INET);
print "got a connection from: $client_host",
" [$client_ipnum]\n";
while(<$new_sock> )
{
print $_;
my $comm = `$_`;
print $new_sock "$comm";
}
close($new_sock);
}
$readable_handles = new IO::Select();
$readable_handles->add($main_sock);
while (1)
{
($new_readable) = IO::Select->select($readable_handles, undef, undef, 0);
foreach $sock (@$new_readable)
{
if ($sock == $main_sock)
{
$new_sock = $sock->accept();
$readable_handles->add($new_sock);
}
else
{
$buf = <$sock>;
if ($buf)
{
print "$buf\n";
my @sockets = $readable_handles->can_write();
print $sock "You sent $buf\n";
foreach my $sck(@sockets){print $sck "$buf\n";}
}
else
{
$readable_handles->remove($sock);
close($sock);
}
}
}
}
print "Terminating Server\n";
close $main_sock;
getc();
*THE CLIENT SCRIPT
########################################
############################
*#!/usr/bin/perl
#use strict;
use IO::Socket;
my ( $host, $port, $kidpid, $handle, $line );
( $host, $port ) = ('10.5.2.174',12000);
my $name = shift || '';
if($name eq ''){print "Enter the command to run?\n"}
chomp ($name = <> );
# create a tcp connection to the specified host and port
$handle = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => $host,
PeerPort => $port
) or die "can't connect to port $port on $host: $!";
$handle->autoflush(1); #output gets there right away
print STDERR "[Connected to $host:$port]\n";
print $handle "Hello $name!\n";
# split the program into two processes, identical twins
die "can't fork: $!" unless defined( $kidpid = fork() );
# the if{} block runs only in the parent process
if ($kidpid)
{
# copy the socket to standard output
while ( defined( $line = <$handle> ) )
{
print STDOUT $line;
}
kill( "TERM", $kidpid ); # send SIGTERM to child
}
# the else{} block runs only in the child process
else {
# copy standard input to the socket
while ( defined( $line = <STDIN> ) )
{
print $handle "$line";
}
}
*
*
On Wed, Mar 19, 2008 at 7:05 PM, zentara <zentara@highstream.net> wrote:
> On Tue, 18 Mar 2008 22:16:28 +0530, anirban.adhikary@gmail.com ("Anirban
> Adhikary") wrote:
>
> my
> to
> If
> side
>
> Hi, for a good tutorial about the basics of sockets, see
> http://www.cs.uno.edu/~golden/teach.html<http://www.cs.uno.edu/%7Egolden/teach.html> and look for the
> Perl socket examples. He does it from the basic level but explains
> what each step does in detail.
> Then you can move up from using the basic Sockets and select, to the
> easier modules IO::Socket and IO::Select ( which handle many of the
> tedious details for you).
>
>
> For a good example of problems using sockets to send data on demand,
> see http://perlmonks.org?node_id=627553
>
>
> For things like executing remote commands on a server, it is highly
> recommended to use ssh instead, for security reasons.
> See http://perlmonks.org?node_id=569657 for a demo of how
> to use Net::SSH2 which is the starte of the art preferred module now.
> It shows how to run system commands like ls.
>
> zentara
>
>
> --
> I'm not really a human, but I play one on earth.
> http://zentara.net/japh.html
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe@perl.org
> For additional commands, e-mail: beginners-help@perl.org
> http://learn.perl.org/
>
>
>
| |
| gulsuner@bilkent.edu.tr 2008-03-20, 4:02 am |
| Hi,
You can fork for multiple connections. and define $SIG{INT} for ctrl-c:
Here is an example;
$SIG{INT} = \&destroy_server; #ctrl -> destroy_server
....
....
....
die "can not fork: $!" unless defined ($kid_pid=fork());
if ($kid_pid) {
while(<$new_sock> ) {
print $_;
my $comm = `$_`;
print $new_sock $comm;
}
close ($new_sock);
}
...
...
...
sub destroy_server {
print $new_sock "Server is destroyed\n";
exit;
}
==
Final code:
#!/usr/bin/perl
use IO::Socket;
use IO::Select;
my @sockets;
my $machine_addr = '127.0.0.1';
$SIG{INT} = \&quit_srv;
$main_sock = new IO::Socket::INET(LocalAddr=>$machine_addr,
LocalPort=>12000,
Proto=>'tcp',
Listen=>3,
Reuse=>1,
);
die "Could not connect: $!" unless $main_sock;
print "Starting Server\n";
my($new_sock, $c_addr, $buf);
while (($new_sock, $c_addr) = $main_sock->accept())
{
my ($client_port, $c_ip) =
sockaddr_in($c_addr);
my $client_ipnum = inet_ntoa($c_ip);
my $client_host =
gethostbyaddr($c_ip, AF_INET);
print "got a connection from: $client_host",
" [$client_ipnum]\n";
die "can't fork: $!" unless defined ($kidpid=fork());
if ($kidpid) {
while(<$new_sock> )
{
print $_;
my $comm = `$_`;
print $new_sock "$comm";
}
close($new_sock);
}
}
$readable_handles = new IO::Select();
$readable_handles->add($main_sock);
while (1)
{
($new_readable) = IO::Select->select($readable_handles, undef, undef,
0);
foreach $sock (@$new_readable)
{
if ($sock == $main_sock)
{
$new_sock = $sock->accept();
$readable_handles->add($new_sock);
}
else
{
$buf = <$sock>;
if ($buf)
{
print "$buf\n";
my @sockets = $readable_handles->can_write();
print $sock "You sent $buf\n";
foreach my $sck(@sockets){print $sck "$buf\n";}
}
else
{
$readable_handles->remove($sock);
close($sock);
}
}
}
}
print "Terminating Server\n";
close $main_sock;
getc();
sub quit_srv() {
print "Server dest\n";
print $new_sock "Server destroyed\n";
exit;
}
On Thu, 2008-03-20 at 10:24 +0530, Anirban Adhikary wrote:[color=darkred]
> Dear List
> I have able to write the client-server architecture script *( Based on the
> script send by ZENTARA )* which can execute command at the server end and
> display the result at client end . But the problem I am facing that the
> server can not able to support multiple client it is only able to support a
> single client. I am also trying to implement when the server script will
> stopeed *( Like using ctrl +c)* then all clients will get some message from
> server about the connection closing.In the server side when some client get
> disconnected from server some message will get priented in the server
> console . I am posting my code here U guys pls help me how to solve these
> problems.
>
> Thanks & Regards in advance
> Anirban Adhikary.
>
>
> *THE SERVER SCRIPT
> *#######################################
##############################
>
> #!/usr/bin/perl
> use IO::Socket;
> use IO::Select;
> my @sockets;
> my $machine_addr = '10.5.2.174';
> $main_sock = new IO::Socket::INET(LocalAddr=>$machine_addr,
> LocalPort=>12000,
> Proto=>'tcp',
> Listen=>3,
> Reuse=>1,
> );
> die "Could not connect: $!" unless $main_sock;
> print "Starting Server\n";
> my($new_sock, $c_addr, $buf);
> while (($new_sock, $c_addr) = $main_sock->accept())
> {
> my ($client_port, $c_ip) =
> sockaddr_in($c_addr);
> my $client_ipnum = inet_ntoa($c_ip);
> my $client_host =
> gethostbyaddr($c_ip, AF_INET);
> print "got a connection from: $client_host",
> " [$client_ipnum]\n";
>
> while(<$new_sock> )
> {
> print $_;
> my $comm = `$_`;
> print $new_sock "$comm";
> }
> close($new_sock);
> }
>
> $readable_handles = new IO::Select();
> $readable_handles->add($main_sock);
>
> while (1)
> {
> ($new_readable) = IO::Select->select($readable_handles, undef, undef, 0);
> foreach $sock (@$new_readable)
> {
> if ($sock == $main_sock)
> {
> $new_sock = $sock->accept();
> $readable_handles->add($new_sock);
> }
> else
> {
> $buf = <$sock>;
> if ($buf)
> {
> print "$buf\n";
> my @sockets = $readable_handles->can_write();
> print $sock "You sent $buf\n";
> foreach my $sck(@sockets){print $sck "$buf\n";}
> }
> else
> {
> $readable_handles->remove($sock);
> close($sock);
> }
> }
> }
> }
> print "Terminating Server\n";
> close $main_sock;
> getc();
>
>
>
> *THE CLIENT SCRIPT
> ########################################
############################
>
> *#!/usr/bin/perl
> #use strict;
> use IO::Socket;
> my ( $host, $port, $kidpid, $handle, $line );
> ( $host, $port ) = ('10.5.2.174',12000);
> my $name = shift || '';
> if($name eq ''){print "Enter the command to run?\n"}
> chomp ($name = <> );
>
> # create a tcp connection to the specified host and port
> $handle = IO::Socket::INET->new(
> Proto => "tcp",
> PeerAddr => $host,
> PeerPort => $port
> ) or die "can't connect to port $port on $host: $!";
> $handle->autoflush(1); #output gets there right away
>
> print STDERR "[Connected to $host:$port]\n";
> print $handle "Hello $name!\n";
>
> # split the program into two processes, identical twins
> die "can't fork: $!" unless defined( $kidpid = fork() );
>
> # the if{} block runs only in the parent process
> if ($kidpid)
> {
> # copy the socket to standard output
> while ( defined( $line = <$handle> ) )
> {
> print STDOUT $line;
> }
> kill( "TERM", $kidpid ); # send SIGTERM to child
> }
>
> # the else{} block runs only in the child process
> else {
> # copy standard input to the socket
> while ( defined( $line = <STDIN> ) )
> {
> print $handle "$line";
>
> }
> }
> *
> *
> On Wed, Mar 19, 2008 at 7:05 PM, zentara <zentara@highstream.net> wrote:
>
|
|
|
|
|