in reply to Re: Socket Listener
in thread Socket Listener

This node falls below the community's threshold of quality. You may see it by logging in.

Replies are listed 'Best First'.
Re^3: Socket Listener
by gman (Friar) on Mar 31, 2010 at 16:43 UTC

    Out of the PEO doc

    #!/usr/bin/perl # This sample sets up two servers. One of them accepts an input feed # from its clients and broadcasts that input to the clients of the # other. For lack of a better name, I've called this a tcp bridge. # This version supports multiple feeds and multiple data consumers. # Every feed will broadcast to every consumer. # A lot of people are confused by the array slice convention for event # handler parameters. The reasons for it are explained here: # http://poe.perl.org/?POE_FAQ/Why_does_POE_pass_parameters_as_array_s +lices # This sample requires POE version 0.1702 or higher. Please see: # http://poe.perl.org/?Where_to_Get_POE # About the KERNEL, HEAP, and ARG0-style parameters: # KERNEL is a reference to POE's main module, POE::Kernel. It holds # most of the low-level functions for posting events, watching files, # setting timers, and so on. # HEAP is a reference to a per-session storage space. If you're # familiar with threads, it is similar to thread-local storage. # Because POE includes several runtime context parameters with every # event, any parameters you include have been pushed to higher places # in @_. ARG0 is the offset of the first real parameter in @_, and # ARG1..ARG9 are conveniences. Because the real parameters are always # at the end of @_, it's possible to retrieve them all at once with: # my (@args) = @_[ARG0..$#_] use warnings; use strict; # Use POE and also the TCP server component. use POE qw(Component::Server::TCP Filter::Line); $/ = 'K'; sub FEED_SERVER_PORT () { 8001 } sub CONSUMER_SERVER_PORT () { 3001 } # A helper to log things. You could also use POE::Component::Logger # to direct logging to a file or syslog. sub printlog { my $message_string = join ( "", @_ ); my $date_string = localtime(); print "$date_string $message_string\n"; } # A table of data consumers. Input from clients attached to the feed # server will be broadcast to every consumer listed in this table. my %clients; # The feed server. Whatever is sent to this server will be broadcast # to every consumer. POE::Component::Server::TCP->new ( Port => FEED_SERVER_PORT, ClientFilter => [ "POE::Filter::Line", Literal =>"K" ], # "\x4B" ] +, # A server error occurred. Perform a graceless stop. Error => sub { my ( $syscall, $error_number, $error_message ) = @_[ ARG0 .. A +RG2 ]; die ( "Couldn't start feed server: ", "$syscall error $error_number: $error_message" ); }, # Log that a client has connected to the feed server. ClientConnected => sub { my $client_id = $_[SESSION]->ID(); printlog("Feed connection $client_id started."); }, # Log that a client has disconnected from the feed server. ClientDisconnected => sub { my $client_id = $_[SESSION]->ID(); printlog("Feed connection $client_id stopped."); }, # Broadcast all feed input to any data consumers out there. This # posts a message to each client session, requesting that it send # the input to its client socket. ClientInput => sub { my ( $kernel, $input ) = @_[ KERNEL, ARG0 ]; foreach my $client_id ( keys %clients ) { $kernel->post( $client_id => send_message => $input ); } }, ); # The consumer server. Every consumer connection will receive what # was sent to each feed connection. POE::Component::Server::TCP->new ( Port => CONSUMER_SERVER_PORT, #Filter => [ "POE::Filter::Line", Literal => "\x4B" ], # A server error occurred. Perform a graceless stop. Error => sub { my ( $syscall, $error_number, $error_message ) = @_[ ARG0 .. A +RG2 ]; die ( "Couldn't start consumer server: ", "$syscall error $error_number: $error_message" ); }, # Register new connections with the clients table, and log their # connections. ClientConnected => sub { my $client_id = $_[SESSION]->ID(); $clients{$client_id} = "alive"; printlog("Consuming connection $client_id started."); }, # Remove departing connections from the clients table, and log # their disconnections. ClientDisconnected => sub { my $client_id = $_[SESSION]->ID(); delete $clients{$client_id}; printlog("Consuming connection $client_id stopped."); }, # Ignore client input. Data consumers cannot talk back to their # feeds. ClientInput => sub { # Do nothing. }, # Custom event handlers go here. The "send_message" event # requests that we send something to the client. InlineStates => { send_message => sub { my ( $heap, $message ) = @_[ HEAP, ARG0 ]; $heap->{client}->put($message); }, }, ); # Run the servers until something stops them. printlog( "Feed server listening on port ", FEED_SERVER_PORT ); printlog( "Consumer server listening on port ", CONSUMER_SERVER_PORT ) +; $poe_kernel->run(); exit 0;
      If anyone is still watching, this seems to get me started. I couldn't get the POE to work for me.
      use IO::Socket; my $sock = new IO::Socket::INET ( LocalHost => 'nonsvch', LocalPort => '6543', Proto => 'tcp', Listen => 1, Reuse => 1, ); die "Could not create socket: $!\n" unless $sock; my $new_sock = $sock->accept(); while(<$new_sock>) { print $_; } close($sock);
      It works ok if I telnet to it, type and hit return, but my feed has no CRLF, it does however have end of record strings
      =*=
      so how do I make it read without blocking for CRLF ? Thanks

        Try using recv instead of the diamond operator.

        Update: Or setting $/ = '=*=';


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re^3: Socket Listener
by marto (Cardinal) on Apr 01, 2010 at 08:40 UTC

    "thanks for the lecture.

    You're welcome.

    "Handling an unformatted data stream coming in on a socket surely has been done before"

    I'm sure it has, which is why I pointed you towards sections of this site containing networking code and tutorials, as well as suggested you look at some frameworks on cpan. You really should do the bare minimum research before posting.

    "I wasn't asking for code to be written, rather a code snippet of something already done."

    See my previous response.

      Sorry to have inconvenienced you. I am sure you have better things to do than provide minimum guidelines to the unwashed....maybe not.