How about actually using a socket, then?
What kind of problem are you trying to solve?
Nothing except true INET sockets will be selectable on Win32 due the different way sockets are implemented.
| [reply] |
If only a true socket is selectable, then I will likely have to approach it that way.
I was hoping that I could just have one object, to which I could write, and then read what I just wrote. By using normal sockets, I'll have to put together a pair of them, and in order to do that, I'll have to set one up for listen mode and then accept() on it. I think that I'll have to be multithreaded to do that, which I've managed to avoid thus far. That, if nothing else, is the reason why I'm not eager to bite the bullet.
Perhaps I should ask a different question... is there a way (without multithreading) to connect two sockets to talk to each other?
If I could work that bit of magic, then I could make a class that looks like just one object, but I could sysread() on one socket and syswrite() on the other, giving the appearance of a loopback or echoing socket.
| [reply] |
I'm going to mostly answer my own question here.
It looks like there's nothing off-the-shelf that implements a loopback socket. If someone finds something, please let me know.
However, there is a way (at least on my win32 box) that will tie a pair of sockets together without the need for multithreading.
The magic function is called socketpair. The docs say that some pipes are implemented by way of this function call (but even if this is true on win32, the resultant objects were not select()able, so they were of no use to me). The socketpair interface creates two genuine sockets and ties them together for you.
I've taken an example using socketpair() and updated it to use IO::Handle objects, which can be easily passed around to other parts of the code. I also demonstrated the use of select() on the socket handles. I didn't call shutdown() on either handle, so they can both read/write from/to each other (refer to perldoc -f socketpair to see an example of shutdown()).
#!perl -w
use strict;
use Socket; # for AF_UNIX, SOCK_STREAM, PF_UNSPEC
use IO::Handle; # for autoflush and object constructor
use IO::Select; # to demonstrate select()ability
my $line;
my $child = IO::Handle->new();
my $parent = IO::Handle->new();
socketpair($child, $parent, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
or die "socketpair: $!";
my %names =
(
$parent->fileno() => 'Parent',
$child ->fileno() => 'Child',
);
$child ->autoflush(1);
$parent->autoflush(1);
my $sel = IO::Select->new( $child, $parent );
$child ->print( "Hello, Parent\n" );
$parent->print( "Hello, Child\n" );
my @ready = $sel->can_read(0.1);
print "There are ${\$sel->count} readable handles\n";
foreach my $ready ( @ready )
{
my $name = $names{ $ready->fileno() };
print "$name receives: " . $ready->getline();
}
$child->close();
$parent->close();
| [reply] [d/l] [select] |