If I understand you correctly your problem is host B. You want to read 2 streams at the same time.
There are many solutions. The simplest is certainly a forking server. After accept()ing a new client the process calls fork(). The parent process closes the client connection and waits for the next client while the child handles the connection.
Another way is to use select() (or IO::Select) with nonblocking IO. There are many examples on the Internet I believe.
Then there are various event modules that do basically the same as select() but often more effectively. These come to mind: Event, Event::Lib, EV, POE, AnyEvent
Then there are perl's ithreads. (use threads;)
And in the end there is Coro. If I where you I'd go either with this one or code a forking server.
Torsten | [reply] |
IO::Select could work too. Get a list of the connections that have data to read from using IO::Select->select, and then read a line from each of them before going back to wait for more input. Only read from the sockets that have something to read, and you won't block.
my $readable = IO::Select->new;
$readable->add($oneSock, $twoSock, $redSock, $blueSock);
while (not $done)
{
my $ready = IO::Select->select($readable);
foreach my $socket (@$ready)
{
# Deal with whatever $socket has to say
}
}
| [reply] [d/l] |
In addition to the list of event frameworks kindly provided by tfoertsch, I would like to add my own IO::Lambda,
which I really wish had more adoption and hope everyone else would excuse me for PRing. Anyways. If you feel like trying it, I'd be glad to provide help. Using it, your task would be written basically as such:
use strict;
use IO::Socket;
use IO::Lambda qw(:all);
use IO::Lambda::Socket qw(:all);
my $server = IO::Socket::INET-> new(
Listen => 5,
LocalPort => 10000,
Blocking => 0,
ReuseAddr => 1,
);
die $! unless $server;
lambda {
context $server;
accept {
# socket with an incoming connection
my $conn = shift;
# tell the loop to accept() again
again;
unless ( ref($conn)) {
warn "accept() error:$conn\n" unless ref($conn);
return;
}
# now read all from the new connection
context $conn;
readable {
my $buf;
my $n = sysread( $conn, $buf, 65536);
unless ( defined $n) {
warn "error reading:$!\n";
} elsif ( $n == 0) {
warn "connection closed\n";
} else {
print $buf;
again;
}
}}
}-> wait;
Hope it helps | [reply] [d/l] |
File::Tail has native support for this. Search its documentation for the select method. It even has an example.
Update: I thought you had mentioned you were using File::Tail. Ignore this post, it won't help you since File::Tail won't work with sockets. You need IO::Select
| [reply] [d/l] |