in reply to Re: IO::Socket Bi-directional comm
in thread IO::Socket Bi-directional comm

I appreciate your feedback.

I realize one side of this problem isn't Perl, but what I was aiming for with my question was if someone else had some example code (client/server) that would demonstrate more two-way communication. I didn't post the whole thing, because my sub was only somewhat modified from the original example in the perlipc docs for the calc server. If you look at the IO::Socket, multi-threaded example, that IS my script. I just don't need a calculator server. =)

My daemon needs to accept a connection, and then print all of the command output from the client to a log file (taking the multi-threaded facet into consideration).

So, to summarize, I am asking if someone has some good sample code showing:

1. Client makes a connection to server
2. Server prints stuff to client socket
3. The results of that input to the client (the client output) is captured by the server.


Again, thank you for responding to my post. =) I apologize for not being more clear the first time.

Replies are listed 'Best First'.
Re^3: IO::Socket Bi-directional comm
by zentara (Cardinal) on Jan 28, 2006 at 12:15 UTC
    Check out Sockets-File-Upload with Net::EasyTCP. It carries on a dialog between client and server, and saves a file. It could easily be extended/modified to do what you want. The only drawback to using Net::EasyTCP is that it uses IO::Select to handle multiple connections. (as opposed to forking or threading). This means that one long connection to a client will block connections from other clients, so it will be good if the exchanges are relatively short.

    Also check out ztk-enchat encrypted server client for a Tk gui version doing chat, in case you want a gui.

    These are just my old code, others may have better code examples suited to your purpose. Net::EasyTCP is nice to use, because it lets you have password-protected ports, automatic encryption, and it will stingify hashes for you, so you can actually pass hashes of data through the socket.


    I'm not really a human, but I play one on earth. flash japh
      I've narrowed it down to a small section:

      while ( <$client> ) { next unless /\S/; # blank line if (/quit|exit/i) { last; } elsif (/microsoft/i) {foreach $command(@commands) { print $client "$command\r"; } } else { last; } } continue { }

      So, we skip empty lines; if we see "quit/exit", we close the socket, if we see "microsoft", we send a list of commands to the client, and that's where the problem crops up; I know it prints the whole list of commands to the client if the code is left like this, but I want the results of these commands, so I added:
      while ( <$client> ) { next unless /\S/; # blank line if (/quit|exit/i) { last; } elsif (/microsoft/i) {foreach $command(@commands) { print $client "$command\r"; while( <$client> ) { print;} } } else { last; } } continue { }
      Now, what happens is I get ALL the output from the first command I sent to $client, but the foreach loop is no longer able to iterate through all of "@commands" because I think it's hanging in the "while" loop. I have tried various things like putting "next;" after "print;", but I either get none of the command output, or I get what I want, but only for the first command, and then the client never closes it's connection (I send "exit" as the third command). I am trying to figure out if I'm just coming at this the wrong way (I have put various print statements within the top "while" loop, as well as trying to create an array to which all output would be stored, and then print the array:
      while ( <$client> ) { while( my @response = <$client>) { next unless /\S/; # blank line if (/quit|exit/i) { last; } elsif (/microsoft/i) {foreach $command(@commands) { print $client "$command\r"; } print @client; } else { last; } } continue { } }
      None of it is getting the results I want. #######################
      Just in case anyone ever runs into this.. I figured it out:
      ... snip ... open(LOGFILE,>>"mylog.log") or die "Can't open mylog.log\n"; print $client "$cmds\r"; while( <$client> ) { print LOGFILE; } close $client; }
      What I wanted to do was print commands to a netcat listener that was setup with "-e cmd.exe" (a la "reverse telnet") and capture all the output to a log file. Print commands to the socket, then do a "while( <$client>)". That seems to get the job done.

      Good luck, and thanks for all the input.
        Yeah, it's kind of hard for me to get my head around your script, since I'm not running it. That else {last;} line looks suspicious to me, since it's in an if-elsif-else chain. Maybe try to put a next in there instead and see what happens.

        But from my experiences with sockets, it sounds like you might be looking for the recv method?. You need to tell the socket to go from sending mode to receive mode. But there are so many different ways to do it, it is hard to say what your problem is with just a code fragment.

        $server->recv($data, 1024); print "received: $data";

        If you can set up a client server script pair, which simply demonstrates your idea, you might want to post it as another new question. You can set them up to just work on localhost. Try to explain what you want the server to do, and what you expect the client to do. If you don't have a clue on how to setup the scripts with pure Perl, just ask, and you will probably get a few pre-made examples. I usually like to working with a forking server and client pair, so that each socket is setup as a one way channel, and you don't need to worry about switching them from send to recv.

        Here is a server client pair you might want to look at:


        I'm not really a human, but I play one on earth. flash japh
      Much thanks brother. I'll check it out.