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

I've been banging my head against this for quite a while now and I've decided I just don't have enough networking experience to figure it out on my own.

I'm trying to write a multi-user, interactive server script. I've put together a basic server using IO::Select without a huge amount of pain thanks to some excellent advice from the Monks and Lincoln D. Stein's "Network Programming with Perl" book. The way my current implementation works is by having an IO::Select switch in the main program with a module to handle the individual connections.

I'm trying to figure out a good way to make the networking modular so that if I feel like changing from IO::Select to a forking model (such as if I'm moving the code from OS to OS), I can do that with only minor changes to the code. Ideally I'd like to be able to say, for example, use MUD::Networking::Fork; instead of use MUD::Networking::Select; and have it work.

I'm starting to wonder if I haven't completely overreached my current ability trying to implement this. Any input would be appreciated.

--
Grant me the wisdom to shut my mouth when I don't know what I'm talking about.

Replies are listed 'Best First'.
Re: Sockets - IO::Select, fork(), and modularity
by tedrek (Pilgrim) on Jun 21, 2003 at 00:37 UTC

    I'm guessing you are writing a MUD server in perl here (given use MUD::Net..., if that's the wrong then the following may have no bearing on reality. :) The reason I'm guessing is because you haven't told us anything more than it's mult-user and a network oriented, which could cover many things, eg a web-server, a bulletin board, a irc server, a multi-player solitaire program....

    No MUD engine I'm aware of forks, the reason is basically that the network interaction is not the difficult/expensive/interesting part of the program, rather the interaction between the entities is eg. Mobs moving/hunting, players chatting, the sky falling :) or another way of putting it, the main loop is timer driven rather than network driven. So, in order to use a forking model you have to either have all that interaction happening in *each* process AND synchronized between the processes or each forked process talking back to a central process which is probably going to be by something like sockets, at which point you've only increased complexity. Theoretically you could have each entity represented by a process and talking to a central process, which may make sense if designed well but that's probably overly complex. Not to mention that when you fork you make a complete copy of all memory which in a MUD could run near 100 Mb easily

    Now that I've told you why I don't think it's a good idea to fork, heres the basic idea of how :) figure out what the network module needs to be able to do, in this case something like read, write, select, connect, disconnect, accept... it doesn't matter how they are implemented, all that matters is given the same arguments they give you the same end result. so accept for fork would be something like

    $sock = $mother->accept(); create sharedmem/pipe/unixsocket; if fork {return identifier($sock)} else {pass_data_between_socket_and_main($sock)}
    and the select version
    $sock = $mother->accept(); push @socks, $sock; return identifier($sock)

    In short you've overreached my ability to come up with a decent reason/design/implementation of forking for a MUD :). However if you are doing something else, specifically something where you basically open connections that don't need to interact with eachother then a forking solution makes much more sense and none of what I've said here applies.

      Thanks for the help! Always appreciated.

      --
      Grant me the wisdom to shut my mouth when I don't know what I'm talking about.