1# $Id: tcp-poe-raw.pl,v 1.1 2009/01/17 11:29:06 dk Exp $
2# An echo client-server benchmark.
3
4use warnings;
5use strict;
6
7use Time::HiRes qw(time);
8use POE;
9use IO::Socket::INET;
10
11my $CYCLES = 500;
12my $port   = 11211;
13
14# Server.  Created before starting the timer, because other benchmarks
15# also do this.
16
17{
18	POE::Session->create(
19		inline_states => {
20			_start          => \&start_server,
21			server_readable => \&accept_connection,
22			client_readable => \&handle_input,
23		},
24	);
25
26	sub start_server {
27		my $serv_sock = IO::Socket::INET-> new(
28			Listen    => 5,
29			LocalPort => $port,
30			Proto     => 'tcp',
31			ReuseAddr => 1,
32		) or die "listen() error: $!\n";
33
34		$_[KERNEL]->select_read($serv_sock, "server_readable");
35	}
36
37	sub accept_connection {
38		my $serv_sock = $_[ARG0];
39		my $conn = IO::Handle->new();
40		accept($conn, $serv_sock) or die "accept() error: $!";
41		$_[KERNEL]->select_read($conn, "client_readable");
42		$conn->blocking(1);
43		$conn->autoflush(1);
44	}
45
46	sub handle_input {
47		my $conn = $_[ARG0];
48		my $input = <$conn>;
49		if (defined $input) {
50			print $conn $input;
51		}
52		else {
53			$_[KERNEL]->select_read($conn, undef);
54		}
55	}
56}
57
58my $t = time;
59
60# Client.
61
62{
63	my $connections = 0;
64
65	POE::Session->create(
66		inline_states => {
67			_start   => sub { _make_connection($_[KERNEL]) },
68			readable => sub {
69				my $sock = $_[ARG0];
70				$_[KERNEL]->select_read($sock, undef);
71				if ($connections >= $CYCLES) {
72					$_[KERNEL]->stop();
73				}
74				else {
75					_make_connection($_[KERNEL]);
76				}
77			}
78		},
79	);
80
81	# Plain helper function.
82	sub _make_connection {
83		my $kernel = shift;
84
85		$connections++;
86		my $x = IO::Socket::INET-> new(
87			PeerAddr  => 'localhost',
88			PeerPort  => $port,
89			Proto     => 'tcp',
90		) or die "connect() error: $!$^E\n";
91
92		$x->autoflush(1);
93		print $x "can write $connections\n";
94
95		$kernel->select_read($x, "readable");
96	}
97}
98
99POE::Kernel->run();
100
101$t = time - $t;
102printf "%.3f sec\n", $t;
103exit;
104