Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   Single command to and from client/server (http://www.velocityreviews.com/forums/t884605-single-command-to-and-from-client-server.html)

Just in 01-14-2004 03:20 AM

Single command to and from client/server
 
List,

From the TCP client with IO::Socket on the perlipc page I have made the
following (apologies for the formatting):

# Server code

use strict;

use warnings;

use IO::Socket;

use Net::hostent;

use Sys::Hostname 'hostname';

$|++;

my $Port = 1971;

my $Host = hostname();

my $Server = IO::Socket::INET->new(Proto => 'tcp', LocalPort => $Port,
Listen => SOMAXCONN, Reuse => 1);

die "Can't setup Server" unless $Server;

print "[Server $Host accepting Clients]\n";

while(my $Client = $Server->accept())

{

$Client->autoflush(1);

print $Client "Connected to $Host\n";

my $HostInfo = gethostbyaddr($Client->peeraddr);

printf "[Connect from %s]\n", $HostInfo->name || $Client->peerhost;

while(<$Client>)

{

print $Client `$_` if /^dir/i;

print $_;

last;

}

close $Client;

}

################################################## ####################

# Client code

#!/usr/local/bin/nsPerl5.005_03/nsperl -w

use strict;

use IO::Socket;

my ($KidPID, $Line);

my $Port = '1971';

my $Host = '123.123.123.123';

my $Handle = IO::Socket::INET->new(Proto => 'tcp', PeerAddr => $Host,
PeerPort => $Port) or die "Cant connect to $Host on $Port:- $!";

$Handle->autoflush(1);

die "Cant fork: $!" unless defined($KidPID = fork());

if($KidPID)

{

while(defined($Line = <$Handle>))

{

print STDOUT $Line;

}

kill("TERM", $KidPID);

}

else

{

print $Handle 'dir d:';

#while(defined($Line = <STDIN>))

#{

# print $Handle $Line;

#}

}

I can get connectivity between the two machines, and with the while
uncommented on the client I can key in "dir d:" and a get a response from
the server.

However what I really need is code that fires off a command from the client
with arguments (without keying it in from STDIN), which can then be picked
up by the server, processed and then returned to the client, closing the
client/connection after the return of data, rather than the continuous
interactive example that I borrowed this code from.

I guess the else in my client is the show stopper because my xterm just sits
there. And when I control C the xterm client the server flushes out the "dir
d:" string to the terminal. So I further guess that I need to close/kill one
of the processes that fork spawns in order for it to return, but I'm not
sure how.

Any help appreciated, thanks.

Just in

P.S./ The client sits on a Solaris machine (Perl 5.5 binary dist), while my
server is on Win2003 server (AS 5.6).



Rocco Caputo 01-14-2004 05:58 AM

Re: Single command to and from client/server
 
On Wed, 14 Jan 2004 11:20:47 +0800, Just in wrote:
> List,
>
> From the TCP client with IO::Socket on the perlipc page I have made the
> following (apologies for the formatting):


[... AIEEE! ...]

>
> ################################################## ####################
>
> # Client code
>
> #!/usr/local/bin/nsPerl5.005_03/nsperl -w
>
> use strict;
>
> use IO::Socket;
>
> my ($KidPID, $Line);
>
> my $Port = '1971';
>
> my $Host = '123.123.123.123';
>
> my $Handle = IO::Socket::INET->new(Proto => 'tcp', PeerAddr => $Host,
> PeerPort => $Port) or die "Cant connect to $Host on $Port:- $!";
>
> $Handle->autoflush(1);
>
> die "Cant fork: $!" unless defined($KidPID = fork());
>
> if($KidPID)
>
> {
>
> while(defined($Line = <$Handle>))
>
> {
>
> print STDOUT $Line;
>
> }
>
> kill("TERM", $KidPID);
>
> }
>
> else
>
> {
>
> print $Handle 'dir d:';
>
> #while(defined($Line = <STDIN>))
>
> #{
>
> # print $Handle $Line;
>
> #}
>
> }
>
> I can get connectivity between the two machines, and with the while
> uncommented on the client I can key in "dir d:" and a get a response from
> the server.
>
> However what I really need is code that fires off a command from the client
> with arguments (without keying it in from STDIN), which can then be picked
> up by the server, processed and then returned to the client, closing the
> client/connection after the return of data, rather than the continuous
> interactive example that I borrowed this code from.


Just to be fair, I should let you know that I've changed your code
without testing it.

# Server code
use strict;
use warnings;
use IO::Socket;
use Net::hostent;
use Sys::Hostname 'hostname';

$|++;

my $Port = 1971;
my $Host = hostname();

my $Server = IO::Socket::INET->new(
Proto => 'tcp', LocalPort => $Port, Listen => SOMAXCONN, Reuse => 1
);

die "Can't setup Server" unless $Server;

print "[Server $Host accepting Clients]\n";

Everything above is pretty much the same. Here you accept new sockets
and run a single command from each. When the command's done, you close
the client and accept another connection.

Yes, it's single-tasking. That is, it can only execute one client's
command at a time. If you want multitasking, try
http://poe.perl.org/?POE_Cookbook/Job_Server or something.

while(my $Client = $Server->accept())
{
$Client->autoflush(1);
print $Client "Connected to $Host\n";
my $HostInfo = gethostbyaddr($Client->peeraddr);
printf "[Connect from %s]\n", $HostInfo->name || $Client->peerhost;

Fetch the command, and remove the newline from it.

my $cmd = <$Client>;
chomp $cmd;

Respond with the results, if it's a valid command. Close the socket
afterwards, disconnecting the client. You did say you wanted to execute
one command noninteractively.

print $Client `$cmd` if /^dir/i;
print $cmd;
close $Client;
}

On the client side, I've put the #! line before the comment. You
probably already had it that way but added the "Client code" comment for
your posting.

By the way, you should really REALLY really REALLY really consider
upgrading Perl. 5.8.2 is years newer than 5.005_03.

#!/usr/local/bin/nsPerl5.005_03/nsperl -w
# Client code

use strict;
use IO::Socket;

my $Port = '1971';
my $Host = '123.123.123.123';

my $Handle = IO::Socket::INET->new(
Proto => 'tcp', PeerAddr => $Host, PeerPort => $Port
) or die "Cant connect to $Host on $Port:- $!";
$Handle->autoflush(1);

print $Handle "dir d:\n";

while(defined($Line = <STDIN>))
{
print $Handle $Line;
}

That non-interactively sends a directory command, reads everything sent
back by the server, and exits when the server closes the connection. No
forking or STDIN are necessary.

> I guess the else in my client is the show stopper because my xterm just sits
> there. And when I control C the xterm client the server flushes out the "dir
> d:" string to the terminal. So I further guess that I need to close/kill one
> of the processes that fork spawns in order for it to return, but I'm not
> sure how.
>
> Any help appreciated, thanks.
>
> Just in
>
> P.S./ The client sits on a Solaris machine (Perl 5.5 binary dist), while my
> server is on Win2003 server (AS 5.6).


--
Rocco Caputo - rcaputo@pobox.com - http://poe.perl.org/

Just in 01-14-2004 07:21 AM

Re: Single command to and from client/server
 
Rocco,

Thanks, but it doesnt work : (
The client just sits there, but if you hit enter on the client the server
replies on its terminal (because of strict and warnings being on) that $cmd
isnt initialised (even when you type in dir d: <enter>)

------8<---------------
> Yes, it's single-tasking. That is, it can only execute one client's
> command at a time. If you want multitasking, try
> http://poe.perl.org/?POE_Cookbook/Job_Server or something.


------8<---------------
Single tasking will be fine for now - the command runs in within a split
second.

------8<---------------
> while(my $Client = $Server->accept())
> {
> $Client->autoflush(1);
> print $Client "Connected to $Host\n";

------8<---------------
Unfortunately "Connected to $Host" goes to the server terminal rather than
my client. I dont really need this, so it doesnt really matter.

------8<---------------
> Respond with the results, if it's a valid command. Close the socket
> afterwards, disconnecting the client. You did say you wanted to execute
> one command noninteractively.


------8<---------------
Yeah, but I cant even get a dir listing, and nothing goes to my client

------8<---------------
> On the client side, I've put the #! line before the comment. You
> probably already had it that way but added the "Client code" comment for
> your posting.


------8<---------------
Yup, youre right.

------8<---------------
> By the way, you should really REALLY really REALLY really consider
> upgrading Perl. 5.8.2 is years newer than 5.005_03.


------8<---------------
No can do, IT own the setup, I'm just an engineer.

------8<---------------
> #!/usr/local/bin/nsPerl5.005_03/nsperl -w
> # Client code


------8<---------------
> print $Handle "dir d:\n";
>
> while(defined($Line = <STDIN>))
> {
> print $Handle $Line;
> }


------8<---------------
Since it doesnt work and not being sure why you put STDIN in there, I tried
changing it to <$Handle> but to no avail. Is it correct?

------8<---------------
> That non-interactively sends a directory command, reads everything sent
> back by the server, and exits when the server closes the connection. No
> forking or STDIN are necessary.


------8<---------------
Hmm, see above.

Hope you can still help out to get this running.

Just in



Just in 01-14-2004 07:43 AM

Re: Single command to and from client/server
 
---------8<----------
"Just in" <goth1938@hotmail.com> wrote in message
news:bu2qm1$hmu$1@news01.intel.com...
> Rocco,
>
> Thanks, but it doesnt work : (
> The client just sits there, but if you hit enter on the client the server
> replies on its terminal (because of strict and warnings being on) that

$cmd
> isnt initialised (even when you type in dir d: <enter>)

---------8<----------

Ignore the above. I fiddled around a bit longer and got it going. The
difference being that I had to put the fork back in, and put a \n after the
"dir d:" - Thats another thing, the single quotes werent helping because
they werent interpreting. Server code remains as what perlipc had it.

Thanks man,

Just in




All times are GMT. The time now is 09:31 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.