Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Passing a socket to a parent

by suaveant (Parson)
on Jun 04, 2002 at 01:15 UTC ( [id://171374]=perlquestion: print w/replies, xml ) Need Help??

suaveant has asked for the wisdom of the Perl Monks concerning the following question:

I am working on a perl gnutella client (yes, if it ever becomes useful I will let people know...) and I am trying to make a child process which tries to make connections to new servents, passing the socket back to the parent on success. Since many connection attempts fail this would allow the existing connections to go on their merry way while bad connections were timing out, etc...

My problem is that I don't know how to pass the socket... I have an idea it has to do with the fileno of the socket, but I have been looking around and either there are no examples out there or I can't find the right question. Can this be done, and, if possible, can it be done and still use IO::Socket on the parent side?

                - Ant
                - Some of my best work - (1 2 3)

Replies are listed 'Best First'.
Re: Passing a socket to a parent
by termix (Beadle) on Jun 04, 2002 at 01:57 UTC

    On a (sufficiently) UNIX system when you create a child process by forking, the child process inherits open file descriptors from the parent (server parents most often use this to share the "listen" socket with a host of children). What you want to do is take a file descriptor created and obtained by the "child" to be handed back to the parent. I don't think that is possible (again, in UNIX).

    You can certainly keep the child around and have it use a preexisting connection with the parent to keep using the connection it created. So everytime you create a child, have a file descriptor created between the parent and the child that is used by the child to "forward" traffic back to the parent. Then when the child starts, it can attempt a connection with the server and if succeeds, it tells the parent: which kills all the other children, and then deals with the child as the forwarder to the socket.

    Another way to do this could be to have siblings that go at it, and the first successful connection has the parent kill all the other children. Then the successful child continues as the main application, while the parent hangs around to handle the signals etc. Coordination is still required, but the child does not have to be coded as a special gateway.

    You can also use pipes and redirects to use STDIN/OUT for these purposes, but one thing I am pretty sure of is that the socket will be killed (shutdown) if your child that created it exits.

    -- termix

      This is in fact possible with UN*X. It's just not easy. It is exactly what lingerd does

      --
      perl -pew "s/\b;([mnst])/'$1/g"

      Doh! Yeah.. I'm using Linux...

      I thought you could pass a socket, similar to the way you can pass an open filehandle, but I certainly could be wrong...

                      - Ant
                      - Some of my best work - (1 2 3)

Re: Passing a socket to a parent
by samtregar (Abbot) on Jun 04, 2002 at 02:42 UTC
    I think it might be possible, but have you considered using select() or IO::Poll instead? It might be less work than trying to pass sockets around between processes and it should scale better. Forking a few children is fine, but forking a couple hundred will cause problems.

    I bet those shiny new books on network programming in Perl have something you could use...

    -sam

      I am using select, but since I am doing thousands of connects (flaw in gnutella spec, lists files sharing and kb shared on pong, but not how many open connection slots they have available...). This tends to chew into my good old packet handling time, which there is quite a lot of, due to the nature of gnutella.

                      - Ant
                      - Some of my best work - (1 2 3)

        Does that mean you intend to solve the problem by forking thousands of children? If so, I don't think that will result in much of an improvement! Have you tried IO::Poll? Rumor has it that it's capable of better performance than good ol' select().

        -sam

Re: Passing a socket to a parent
by Abigail-II (Bishop) on Jun 04, 2002 at 12:01 UTC
    Yes, you can. It's not portable though, so be aware. It isn't trivial either, and there isn't any specific Perl support for it. Under System V Release 4, you would use a stream pipe and ioctl. On BSD, you would use a Unix Domain Socket.

    Details, including example code (in C), are to be found in Stevens' Advanced Programming in the UNIX Environment in the chapter Advanced Interprocess Communication.

    Abigail

Re: Passing a socket to a parent
by perrin (Chancellor) on Jun 04, 2002 at 04:05 UTC
      Cool module, but since when are file descriptors called "access rights"? Shouldn't that Socket::PassFD?

      -sam

Re: Passing a socket to a parent
by perigeeV (Hermit) on Jun 04, 2002 at 16:58 UTC

    This doesn't answer your direct question, but you may wish to know of the existance of Net::Gnutella. I haven't tried it myself though.


      Oh.. I know... and I am using it as a reference for parsing in a couple of places, but overall I found the package miserable to work with, with little or no documentation... it also has never been updated, apparently... also, I am looking for a finer grained control over my setup... but thanks...

                      - Ant
                      - Some of my best work - (1 2 3)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://171374]
Approved by rob_au
Front-paged by samtregar
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2024-04-19 11:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found