Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Could you fellows please help?

I am working on a PERL program that recieves information at a certain port (say port 2000), and sends it to various peers. For the time being, though, I'm just trying to get it to take in the information and send it back to the program.

What I would like to do is allow another program (different from PERL), to connect to it, then have the information from that connection "branched" to other programs connected it. Is there a way to do this? For the time being I'm using IO::Socket::INET. Will this module work?

#!/usr/bin/perl #The usual modules use strict; use IO::Socket::INET; #Make a constant connection (may have to use the "constant" module) use constant GOING => '66.78.26.27'; use constant PORT => '2000'; #Create a new object and set up the protocol to Transmittion Control P +rotocol and the Local Port to PORT. my $Socky = IO::Socket::INET->new(Proto => 'tcp', PeerPort => PORT, PeerAddr => GOING); while (1) { #This always returns true, thus giving a continual loop. Send_It(<$Socky>); } sub Send_It { my @All_of_me = @_; $Socky->send(@All_of_me); } exit;

Replies are listed 'Best First'.
Re: Sending and recieving data
by jepri (Parson) on Feb 24, 2003 at 04:06 UTC
    I can see you've got some code going, but you're going to need to make a structured plan. Start off by opening any outgoing sockets that you need, then wait for a connection on a local port. When you get the connection, you'll need to accept it, then do non-blocking reads while checking for new connections. It's fairly complicated.

    If you don't want to get that complicated, try POE.

    ____________________
    Jeremy
    I didn't believe in evil until I dated it.

      Just my opinion, but POE is far more complicated.

        While I would agree that if you look at POE from a low level, there is quite a learning curve to surmount - However, for use in a real-world, practical sense, POE isn't nearly as difficult as it first seems. The documentation at http://poe.perl.org is a bit patchy in places, but it is improving.

        For example, from the POE cookbook documentation, the following code acts as a non-blocking echo server, much like what the venerable Anonymous Monk seeks and is relatively straight-forward to follow:

        #!/usr/bin/perl use POE; use POE::Component::Server::TCP; use strict; POE::Component::Server::TCP->new ( 'Alias' => "echo", 'Port' => 2000, 'ClientInput' => sub { my ( $session, $heap, $input ) = @_[ SESSION, HEAP, ARG0 ]; $heap->{client}->put($input); } ); $poe_kernel->run(); exit 0;

         

        perl -le 'print+unpack("N",pack("B32","00000000000000000000001000110100"))'

Re: Sending and recieving data
by pg (Canon) on Feb 24, 2003 at 05:00 UTC
    Generally speaking, your idea would fly. (It is not clear to me whether your main concern is that you used different languages at different nodes. that should be okay, TCP itself has nothing to do with programming language)

    I once did something called message router, which is a set of libraries for a private user level protocol used in my shop. The library has three versions, one in Perl, one in c, and one in java, so all the other programmers in my shop can call it, doesn't matter whether he/she is a Perl/c/Java programmer.

    Those libraries worked fine.

    In your case, I suspect that it might be better if you create one more level of abstraction on top of TCP, to handle your user level message routing. Not sure, depends on your requirement, what I said is just my experience and my solution at that time.

    As for IO::Socket::INET, it is just fine, that was what I used.

    If you ask me to revisit it again today, considering the tech progress people made between then and today, I might like to study Java Messaging a little bit, if Perl is not a must. That might help avoiding reinvent the wheel, and gain a more sophisticated solution.
Re: Sending and recieving data
by jasonk (Parson) on Feb 24, 2003 at 03:47 UTC

    There are very good examples of how to create network servers and clients using IO::Socket::INET in the perlipc documentation.

      Not really. There are some brief examples of how to use socket type things in perlipc, but building a relay server is definately beyond the scope of perlipc. It doesn't really go into non-blocking sockets, and the socket server example is pretty brief.

      The best thing to do is grab some code which already does similar stuff, get familiar with it, and then tweak it. I'm sure there are some socket tutorials around, I just don't know of any. Try looking at C ones, since networking in perl and C is almost identical.

      ____________________
      Jeremy
      I didn't believe in evil until I dated it.

        But perlipc will at least give him a starting point, by giving enough information to get the code that he already has to work, you can't take completely broken code and add features like non-blocking IO to it.

Re: Sending and recieving data
by castaway (Parson) on Feb 24, 2003 at 12:05 UTC
    I'm not a fellow, but I'll answer anyway :)
    It's unclear from your code if that is the server you are starting, or a client. If its the server, it should be doing a 'Listen' to the port, accepting client connections, and reading from them, rather than the server itself.
    If it's a client then what you are doing is connecting to a server, looping on the lines read from the server, and sending them back to the server.

    What you need is a server which listens to a port, spawns off 'child-sockets' to deal with the clients, and writes each line received from the clients to the other clients.
    I answered a question similar to this recently, and I have a sneaking feeling it was also from you :)
    Re: Socket: Server shall send same $line to several clients

    The short answer is no, it wont quite work.

    C.

Re: Sending and recieving data
by Coruscate (Sexton) on Feb 24, 2003 at 19:26 UTC

    Another option available to you is the use of Net::Server. Sample, untested code below. It only allows one connection at a time. If you need multiple simultanious client connections, check out the personalities offered by Net::Server (mainly Net::Server::Fork, Net::Server::PreFork, and Net::Server::PreForkSimple.

    #!/usr/bin/perl -w package SimpleServer; use strict; use Net::Server; our @ISA = qw(Net::Server); SimpleServer->run( port => 2000, log_level => 4 ); exit; # The subroutine called when a new client connects sub process_request { my $self = shift; my $client = $self->{'server'}; while (1) { my $txt = <STDIN>; # STDIN and STDOUT are mapped to client $txt =~ s/\r?\n$//; print $txt, "\r\n"; } }


    If the above content is missing any vital points or you feel that any of the information is misleading, incorrect or irrelevant, please feel free to downvote the post. At the same time, reply to this node or /msg me to tell me what is wrong with the post, so that I may update the node to the best of my ability. If you do not inform me as to why the post deserved a downvote, your vote does not have any significance and will be disregarded.

Re: Sending and recieving data
by sth (Priest) on Feb 24, 2003 at 19:36 UTC

    In addition to the good advice you have gottern here, I would recommend getting a copy of "Network Programming with Perl" by Lincoln Stein. Excellent book, lots of usable examples(which you can download), and if you use something like POE, it still is beneficical to know how things are working.

    STH