Here are various ways to implement a simple server. They support multiple simultaneous connections.

Using POE::Component::Server::TCP

This echo server illustrates recent Server::TCP technology. It requires POE 0.1702 or higher. After starting it, telnet to localhost port 11211, and enter some text.

#!/usr/bin/perl

# http://poe.perl.org/?POE_Cookbook/TCP_Servers

use warnings;
use strict;

# Include POE and POE::Component::Server::TCP.

use POE qw(Component::Server::TCP);

# Start a TCP server.  Client input will be logged to the console and
# echoed back to the client, one line at a time.

POE::Component::Server::TCP->new(
  Alias       => "echo_server",
  Port        => 11211,
  ClientInput => sub {
    my ($session, $heap, $input) = @_[SESSION, HEAP, ARG0];
    print "Session ", $session->ID(), " got input: $input\n";
    $heap->{client}->put($input);
  }
);

# Start the server.

$poe_kernel->run();
exit 0;

Using POE::Component::Server::TCP and Filter::SSL

The same as above, but with SSL encryption. Try "openssl s_client -connect localhost:11211", and enter some text.

You need POE::Filter::SSL version 0.20 or later to run this example!

#!/usr/bin/perl

# http://poe.perl.org/?POE_Cookbook/TCP_Servers

use warnings;
use strict;

# Include POE, POE::Component::Server::TCP and POE::Filter::SSL (at least 0.17!).

use POE qw(Component::Server::TCP Filter::SSL Filter::Line);

# Start a TCP server.  Client input will be logged to the console and
# echoed back to the client, one line at a time.

POE::Component::Server::TCP->new(
  Alias => "echo_server",
  Port  => 11211,

  # You need to have created certificates for server mode!

  ClientFilter =>
    ["POE::Filter::SSL", crt => 'server.crt', key => 'server.key'],
  ClientInput => sub {
    my ($session, $heap, $input) = @_[SESSION, HEAP, ARG0];

    # The following line is needed to do the SSL handshake!

    print "Session ", $session->ID(), " got input: $input\n";
    $heap->{client}->put($input);
  }
);

# Start the server.

$poe_kernel->run();
exit 0;

A more advanced example

This echo server illustrates the same Server::TCP technology. This example shows how (and where) more complex processing can be done.

After starting it, telnet to localhost port 11211, and enter some text.

use POE qw(Component::Server::TCP);

use strict;
use warnings;

POE::Session->create(
  inline_states => {
    _start => sub { $_[KERNEL]->alias_set('echo_server') },

    got_line => sub {
      my ($kernel, $heap, $postback, $input) = @_[KERNEL, HEAP, ARG0 .. $#_];

      # stash the postback on the heap
      $heap->{postback} = $postback;
      $kernel->yield(cook_line => $input);
    },

    cook_line => sub {
      my ($heap, $input) = @_[HEAP, ARG0 .. $#_];
      my $postback = $heap->{postback};

      # this example can be expanded by doing
      # something more complex here, SOMETHING,
      # anyway, other than:
      my $output = "INPUT: " . $input;

      $postback->($output);
      }
  }
);

POE::Component::Server::TCP->new(
  Port => 11211,

  # for a more complex application, you can use Filter::Reference to
  # pass complex data structures as input/output.

  # ClientFilter  => "POE::Filter::Reference",

  ClientInput => sub {
    my ($sender, $kernel, $input) = @_[SESSION, KERNEL, ARG0];

    $kernel->post(
      echo_server => got_line => $sender->postback('client_output'),
      $input
    );
  },

  InlineStates => {
    client_output => sub {
      my ($heap, $response) = @_[HEAP, ARG1];

      $heap->{client}->put($response->[0])
        if defined $heap->{client}

          # that is, if $heap->{client} is still connected
      }
  },

);

$poe_kernel->run();

Using SocketFactory and ReadWrite

This echo server creates a listening socket. Telnet to it and type something, pressing enter when you're done. The server will echo it back to you. Sungo

#!/usr/bin/perl

# http://poe.perl.org/?POE_Cookbook/TCP_Servers

use strict;
use warnings;

use Socket;
use POE qw(Wheel::SocketFactory
  Wheel::ReadWrite
  Driver::SysRW
  Filter::Stream
);

#####
# MAIN
#####

local $| = 1;
our $debug      = 1;        # be very very noisy
our $serverport = 11211;    # 'poe' in base10 :P

fork and exit unless $debug;

POE::Session->create(
  inline_states => {
    _start => \&parent_start,
    _stop  => \&parent_stop,

    socket_birth => \&socket_birth,
    socket_death => \&socket_death,
  }
);

# $poe_kernel is exported from POE
$poe_kernel->run();

exit;

####################################

sub parent_start {
  my $heap = $_[HEAP];

  print "= L = Listener birth\n" if $debug;

  $heap->{listener} = POE::Wheel::SocketFactory->new(
    BindAddress  => '127.0.0.1',
    BindPort     => $serverport,
    Reuse        => 'yes',
    SuccessEvent => 'socket_birth',
    FailureEvent => 'socket_death',
  );
}

sub parent_stop {
  my $heap = $_[HEAP];
  delete $heap->{listener};
  delete $heap->{session};
  print "= L = Listener death\n" if $debug;
}

##########
# SOCKET #
##########

sub socket_birth {
  my ($socket, $address, $port) = @_[ARG0, ARG1, ARG2];
  $address = inet_ntoa($address);

  print "= S = Socket birth\n" if $debug;

  POE::Session->create(
    inline_states => {
      _start => \&socket_success,
      _stop  => \&socket_death,

      socket_input => \&socket_input,
      socket_death => \&socket_death,
    },
    args => [$socket, $address, $port],
  );

}

sub socket_death {
  my $heap = $_[HEAP];
  if ($heap->{socket_wheel}) {
    print "= S = Socket death\n" if $debug;
    delete $heap->{socket_wheel};
  }
}

sub socket_success {
  my ($heap, $kernel, $connected_socket, $address, $port) =
    @_[HEAP, KERNEL, ARG0, ARG1, ARG2];

  print "= I = CONNECTION from $address : $port \n" if $debug;

  $heap->{socket_wheel} = POE::Wheel::ReadWrite->new(
    Handle => $connected_socket,
    Driver => POE::Driver::SysRW->new(),
    Filter => POE::Filter::Stream->new(),

    InputEvent => 'socket_input',
    ErrorEvent => 'socket_death',
  );

  $heap->{socket_wheel}->put("1 Welcome. Say something. I'll say it back.\n\n");
}

sub socket_input {
  my ($heap, $buf) = @_[HEAP, ARG0];
  $buf =~ s/[\r\n]//gs;
  $heap->{socket_wheel}->put("$buf\n");
}