[MUD-Dev] Sockets

Alex Stewart riche at crl.com
Wed Apr 21 12:46:25 CEST 1999

"Quzah [softhome]" <quzah at softhome.net> wrote:
> What is the main difference between and benifit of using:
> (1) asynchronous notification
>     <versus>
> (2) versus non-blocking
>     <versus>
> (3) using select

Technically, there are two different issues here, and you'll probably need some
combination of the above options.

First, some definitions:
    (you didn't mention this in your list,  but it's the most basic starting
    point for socket programming, so it should be discussed.  It sounds like
    this is where you are currently with your program)  When you write
    to a socket, it sends the data out.  If there isn't enough buffer space in
    the output buffer for everything you feed it, it will send out as much as
    it can, wait for more space, send out more, etc, and not return until it's
    written everything.  When you read from a socket, it returns any data
    which has come in.  If there's no data in the input buffer, it will wait
    until there is some and then return that.

    This has some obvious drawbacks for handling multiple sockets in the same
    application.  When you're reading/writing with one, your entire application
    is tied up until the operation completes on that socket.

    When a socket is set non-blocking, if you write to it and there isn't
    enough buffer space for all of the data you are writing, it writes as much
    as it can and returns the amount written.  You can then try again to write
    the rest of it at a later time.  When you read from a non-blocking socket,
    if data is available in the input buffer, it is returned.  If no data is
    currently available, the call returns without any data.

    In this way, socket IO never suspends program execution any longer than
    absolutely necessary, but it does mean you need to do a bit more
    housekeeping on your end (knowing when to try writes again, making sure you
    pick up data in a timely manner when it comes in, etc).  This is where
    notification methods come in:

  Repeated polling:
    This is the most obvious way to check for events on sockets.  Just
    repeatedly loop through them and check to see if any are ready to do
    anything you want to do.  While there are a few (very unusual)
    circumstances where this may actually be useful, in general this is a Bad
    Thing(tm), as it means even when your program is completely idle, it'll be
    using up huge amounts of procesing time just doing nothing.  There are
    better ways.

  Asyncrhonous notification:
    This is essentially "interrupt driven" network handling.  When a socket has
    data (or is available for writing more data out), the system notifies the
    application (typically via a signal or a pipe), at which point the
    application services the socket and then continues on with whatever it was
    doing when it was interrupted.

    The main problems with this are that as far as I know, nobody's come up
    with a very good implementation of this for unix (certainly not a portable
    one), and that this method (despite its somewhat cleaner conceptual model)
    doesn't really gain anything over other already well-accepted methods.  In
    any case if you're starting out it's probably better to go with one of the
    more common methods which already have a lot more documentation and
    examples available.

    This is the most common way to deal with network events, and is probably
    what you want to use.  This method involves setting up a structure
    indicating what sockets (or other file descriptors) you're interested in
    and what types of events (ready-for-write, data-available-for-read, etc)
    you're interested in for each socket.  You then pass this information to
    the select() or poll() system call, which sleeps until something happens
    (or a timeout you specify expires).  When one of the events you're waiting
    on occurs, it returns with an indication of what's happened to which
    sockets.  Based on this information, you can then do whatever operations
    are appropriate, and then return to select() or poll() again to wait for
    the next event.

    In case you're wondering, select() is the BSD version and poll() is the
    SysV/POSIX version of more or less the same sort of thing.  They use
    different types of structures and semantics for some things, but when it
    comes right down to it the difference between their functionality is
    basically trivial (particularly since in most modern OSes, the select()
    call is actually a wrapper around poll() anyway).  Since poll() is now the
    standard for, you might want to become familiar with it, but on the other
    hand, select() has a lot more in the way of examples floating around to
    play with, so it's up to you.

Anyway, so what you're probably looking for is using a combination of
non-blocking sockets with select() or poll()..

     Alex Stewart - riche at crl.com - Richelieu @ Diversity University MOO
           "For the world is hollow, and I have touched the sky."

MUD-Dev maillist  -  MUD-Dev at kanga.nu

More information about the mud-dev-archive mailing list