Non-blocking IO is ja im moment mein Lieblingsthema. :)
Ich würde dir auf jeden Fall auch zu POE raten!!!
Aber hier ein Beispiel mit IO::Poll, das buffern und die sysread/syswrite teile sind bei einer select() Lösung ja identisch.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/perl
# usage: client.pl [host] [port]
use strict;
use IO::Socket;
use IO::Poll 0.04 qw(POLLIN POLLOUT POLLERR POLLHUP);
use Errno qw(EWOULDBLOCK);
use constant MAXBUF => 8192;
$SIG{PIPE} = 'IGNORE';
my ($to_stdout,$to_socket,$stdin_done,$sock_done);
my $host = shift or die "Usage: client.pl host [port]\n";
my $port = shift || 'echo';
my $socket = IO::Socket::INET->new("$host:$port") or die $@;
my $poll = IO::Poll->new() or die "Can't create IO::Poll object";
$poll->mask(\*STDIN => POLLIN);
$poll->mask($socket => POLLIN);
$socket->blocking(0); # turn off blocking on the socket
STDOUT->blocking(0); # and on STDOUT
while ($poll->handles) {
$poll->poll;
#handle readers
for my $handle ($poll->handles(POLLIN|POLLHUP|POLLERR)) {
if ($handle eq \*STDIN) {
$stdin_done++ unless sysread(STDIN,$to_socket,2048,length $to_socket);
}
elsif ($handle eq $socket) {
$sock_done++ unless sysread($socket,$to_stdout,2048,length $to_stdout);
}
}
# handle writers
for my $handle ($poll->handles(POLLOUT|POLLERR)) {
if ($handle eq \*STDOUT) {
my $bytes = syswrite(STDOUT,$to_stdout);
unless ($bytes) {
next if $! == EWOULDBLOCK;
die "write to stdout failed: $!";
}
substr($to_stdout,0,$bytes) = '';
}
elsif ($handle eq $socket) {
my $bytes = syswrite($socket,$to_socket);
unless ($bytes) {
next if $! == EWOULDBLOCK;
die "write to socket failed: $!";
}
substr($to_socket,0,$bytes) = '';
}
}
} continue {
my ($outmask,$inmask,$sockmask) = (0,0,0);
$outmask = POLLOUT if length $to_stdout > 0;
$inmask = POLLIN unless length $to_socket >= MAXBUF
or ($sock_done || $stdin_done);
$sockmask = POLLOUT unless length $to_socket == 0 or $sock_done;
$sockmask |= POLLIN unless length $to_stdout >= MAXBUF or $sock_done;
$poll->mask(\*STDIN => $inmask);
$poll->mask(\*STDOUT => $outmask);
$poll->mask($socket => $sockmask);
$socket->shutdown(1) if $stdin_done and !length($to_socket);
}
\n\n
<!--EDIT|sri|1084884090-->