http://qs1969.pair.com?node_id=634286


in reply to IO::Socket::INET file handler

There are two ways of doing this:
- fork() after you accept(), which gets you one child per connection, or
- threads - create multiple worker threads and pass the file descriptor in.

Since a socket isn't really a shared resource, there are restrictions on how you can connect multiple ends to it. A socket is just a file descriptor, and a process can't get access to another processes's FDs (unless it has root privileges). When you fork, the child process already has the filehandle open, and can use it without any problems, but since you can't get any further access to the parent, where the accept()s are going on, you have to die once you're finished with the current client.

Threads however, all live in the same PID, they just each have their own copy of the perl runtime. They can get at the parent's FDs by passing the file descriptor number around, which you get by running fileno($socket).

I posted a thread a couple of months ago here, which ended up with some really helpful example code from BrowserUk: Resource pools and concurrency

Replies are listed 'Best First'.
Re^2: IO::Socket::INET file handler
by Razvanica (Novice) on Aug 22, 2007 at 10:10 UTC
    Thanks mattk
    In fact I am using fork() on Windows (my bad). However, my problem reduces to something like this:
    My server:
    use IO::Socket; use IO::Select; my $socket= new IO::Socket::INET ( LocalHost => 'localhost', LocalPort => 9000, Proto => 'tcp', Listen => SOMAXCONN, Reuse => 1); if (not defined $socket) { die "no server"; } my $sel= IO::Select->new($socket); print "Waiting for connections on port 9000\n"; my @ready; my $client; my $message; my $new; while (@ready= $sel->can_read) { foreach $client (@ready) { #client speaking if ($client == $socket) { #new client -> add client print "new client\n"; my $add= $client->accept; $sel->add($add); print "added\n"; } else { #old client print "old client \n"; $client->recv($message,256); print $client."\n"; $client->send($client); $client->recv($new, 256); print $new."\n"; $new->send("ok"); } } }

    My client:
    my $sock; my $message; my $socket= new IO::Socket::INET ( PeerHost => 'localhost', PeerPort => 9000, Proto => 'tcp'); if (not defined $socket) { die "no server"; } $socket->send("something"); $socket->recv($sock, 256); $socket->send($sock); $socket->recv($message, 256);
    And this gives me something like:
    Waiting for connections on port 9000 new client added old client IO::Socket::INET=GLOB(0x1b19628) IO::Socket::INET=GLOB(0x1b19628) Can't locate object method "send" via package "IO::Socket::INET=GLOB(0x1b19628)" (perhaps you forgot to load "IO:Socket::INET=GLOB(0x1b19628)"?) at server.pl line 39