Skip to content

Instantly share code, notes, and snippets.

@sekimura
Created January 12, 2009 07:10
Show Gist options
  • Save sekimura/45915 to your computer and use it in GitHub Desktop.
Save sekimura/45915 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
use strict;
use warnings;
use Danga::Socket;
use IO::Socket::INET;
my $conf_port = 20020;
use Socket qw(IPPROTO_TCP SO_KEEPALIVE TCP_NODELAY SOL_SOCKET);
# Linux-specific:
use constant TCP_KEEPIDLE => 4; # Start keeplives after this period
use constant TCP_KEEPINTVL => 5; # Interval between keepalives
use constant TCP_KEEPCNT => 6; # Number of keepalives before death
# establish SERVER socket, bind and listen.
my $server = IO::Socket::INET->new(LocalPort => $conf_port,
Type => SOCK_STREAM,
Proto => IPPROTO_TCP,
Blocking => 0,
Reuse => 1,
Listen => 10 )
or die "Error creating socket: $@\n";
my $accept_handler = sub {
my $csock = $server->accept();
return unless $csock;
IO::Handle::blocking($csock, 0);
setsockopt($csock, IPPROTO_TCP, TCP_NODELAY, pack("l", 1)) or die;
# Enable keep alive
(setsockopt($csock, SOL_SOCKET, SO_KEEPALIVE, pack("l", 1)) &&
setsockopt($csock, IPPROTO_TCP, TCP_KEEPIDLE, pack("l", 30)) &&
setsockopt($csock, IPPROTO_TCP, TCP_KEEPCNT, pack("l", 10)) &&
setsockopt($csock, IPPROTO_TCP, TCP_KEEPINTVL, pack("l", 30)) &&
1
) || die "Couldn't set keep-alive settings on socket (Not on Linux?)";
my $client = Client->new($csock);
$client->watch_read(1);
};
Client->OtherFds(fileno($server) => $accept_handler);
Client->EventLoop();
package Client;
use Danga::Socket;
use base 'Danga::Socket';
use fields ( 'read_buf',);
sub new {
my Client $self = shift;
$self = fields::new($self) unless ref $self;
$self->SUPER::new( @_ );
$self->{read_buf} = '';
return $self;
}
# Client
sub event_read {
my Client $self = shift;
my $bref = $self->read(1024);
return $self->close() unless defined $bref;
$self->{read_buf} .= $$bref;
if ($self->{read_buf} =~ s/^(.+?)\r?\n//) {
my $line = $1;
## echo
$self->write($line."\n");
}
}
# Client
sub event_err { my $self = shift; $self->close; }
sub event_hup { my $self = shift; $self->close; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment