Single command to and from client/server

Discussion in 'Perl Misc' started by Just in, Jan 14, 2004.

  1. Just in

    Just in Guest

    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).
    Just in, Jan 14, 2004
    #1
    1. Advertising

  2. Just in

    Rocco Caputo Guest

    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/
    Rocco Caputo, Jan 14, 2004
    #2
    1. Advertising

  3. Just in

    Just in Guest

    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, Jan 14, 2004
    #3
  4. Just in

    Just in Guest

    ---------8<----------
    "Just in" <> wrote in message
    news:bu2qm1$hmu$...
    > 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
    Just in, Jan 14, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Randall Parker
    Replies:
    1
    Views:
    589
    S. Justin Gengo
    Dec 12, 2005
  2. Chris
    Replies:
    1
    Views:
    13,604
    Oisin
    Mar 24, 2006
  3. -
    Replies:
    2
    Views:
    386
    Alan Krueger
    Jul 29, 2005
  4. chris brat
    Replies:
    1
    Views:
    615
    chris brat
    May 10, 2006
  5. Water Cooler v2
    Replies:
    2
    Views:
    446
    Water Cooler v2
    Apr 18, 2006
Loading...

Share This Page