Created
January 12, 2009 07:10
-
-
Save sekimura/45915 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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