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 -
-
http://poe.perl.org/