This post is part of something new I will be doing every once in a while. I will choose at random from a bunch of SDL libraries (that are good) and feature them here for all of you to check out. Today, we have a library called Net2 created by Bob Pendleton. He has been a frequent SDL contributor for quite a while now, and if you've ever subscribed to the SDL Mailing List, you probably have seen emails from him.

So what is Net2? In a nutshell, it's a layer on top of SDL_net that passes all network communication over SDL's existing event system. In other words, when something happens on the network (such as a new connection, or received data), you will receive an SDL_Event in your primary thread. Additionally, Net2 runs in its own thread and is thread-safe (SDL_net by itself is not thread safe). And lastly, it's super simple to use and it just plain works.

Here's an example TCP Client/Server from the Net2 documentation:

Client
#include <string.h>
#include <stdlib.h>

// The following libraries all have to be included to get all of SDL
// plus the net2 and fastevents libraries. I include my SDLUtils
// library because I have used my initialization and quit functions to
// simplify the code.

#include "SDL.h"
#include "net2.h"
#include "SDLUtils.h"

int main(int argc, char **argv)
{
  char buf[100];                             // storage for a message
  int i;                                     // a counter
  int s = -1;                                // the socket, just an int
  int count = 0;                             // how many messages to send
  int limit = 1000;

  mySDLInitOrQuit(SDL_INIT_EVENTTHREAD |     // initialize SDL. We need
                  SDL_INIT_VIDEO |           // events and it doesn't
                  SDL_INIT_NOPARACHUTE);     // work without video.

// Here we ask for a connection to the computer. In this case we are
// just trying to connect to the computer we are on at port 6666. We
// check to make sure we have a valid connection before going on with
// the rest of the program. Note that the socket id winds up in s.

  if (-1 == (s = NET2_TCPConnectTo("localhost", 6666)))
  {
    printf("ConnectTo failed\n");
    exit(0);
  }

// All we do here is create a message and send it. The message is just
// the words "TCP message" followed by a message number.

  for (i = 0; i < limit; i++)
  {
    memset(buf, 0, sizeof(buf));
    sprintf(buf, "TCP message #%08d\n", i);  // create the message to send
    NET2_TCPSend(s, buf, sizeof(buf));       // send it and count it.
    count += sizeof(buf);
    //printf("%d\n", i);
    //SDL_Delay(1);
  }

  printf("count=%d\n", count);               // tell how many were sent

  mySDL_Quit();                              // clean up.
}
Server
#include <stdlib.h>

// The following libraries all have to be included to get all of SDL
// plus the net2 and fastevents libraries. I include my SDLUtils
// library because I have used my initialization and quit functions to
// simplify the code.

#include "SDL.h"
#include "fastevents.h"
#include "net2.h"
#include "SDLUtils.h"

int main(int argc, char **argv)
{
  SDL_Event ev;                              // an SDL event
  char buf[1024];                            // a message buffer
  int len = 0;                               // some counters
  int count = 0;
  int socks = 0;                             // the number of
                                             // connected sockets,
                                             // which is also the
                                             // number of connected
                                             // clients.

  mySDLInitOrQuit(SDL_INIT_EVENTTHREAD |     // initialize SDL. We need
                  SDL_INIT_VIDEO |           // events and it doesn't
                  SDL_INIT_NOPARACHUTE);     // work without video

// This is where we tell NET2 to start accepting TCP/IP connections on
// port 6666. This call does not wait for a connection to come in. It
// tells NET2 to do the waiting and it returns immediately. After this
// call returns your program will get an event any time a computer
// trys to connect to the port given in this call.

  NET2_TCPAcceptOn(6666);

  while (FE_WaitEvent(&ev))                  // wait for events
  {
    //printSDLEvent(&ev);

    switch (ev.type)
    {

// all NE2 events are SDL_USEREVENTs but not all user events are NET2
// events. If you use user events in your code you need to be careful
// to make sure you are not using the same event codes that NET2 uses.

    case SDL_USEREVENT:
      switch(NET2_GetEventType(&ev))
      {

// This next piece of code handles an accept event. This event tells
// us that an connection has been accepted. Here, all we do is count
// it. You would normally take some other action.

      case NET2_TCPACCEPTEVENT:
        printf("accept(%d)\n", NET2_GetSocket(&ev));
        printNET2Event(&ev);
        socks++;
        break;

        // This next piece of code is for handling receive
        // events. This kind of event tells us we have input waiting
        // on a socket. You need to grab all of it. No that we get the
        // socket from the event. You can use the socket to tell you
        // which user sent the information to you.

      case NET2_TCPRECEIVEEVENT:
        while (0 != (len = NET2_TCPRead(NET2_GetSocket(&ev), buf, sizeof(buf))))
        {
          count += len;
        }
        break;

        // If an error occurs on a socket or the other computer closes
        // the connection you will get a close event. When you get a
        // close event you must close the socket. Use the socket in
        // the event to tell you which connection went away.

      case NET2_TCPCLOSEEVENT:
        printf("close(%d)\n", NET2_GetSocket(&ev));
        printNET2Event(&ev);
        NET2_TCPClose(NET2_GetSocket(&ev));  // close the socket

        printf("count=%d\n", count); fflush(NULL);
        socks--;
        if (0 >= socks)
        {
          //exit(0);
        }
        //count = 0;
        break;

        // Sometimes you will get errors. It is best to keep track of
        // them and try to figure out what is causing them.

      case NET2_ERROREVENT:
        printf("Error: %s(%d)\n", NET2_GetEventError(&ev), NET2_GetSocket(&ev));
        printNET2Event(&ev);
        break;
      }
      break;

    case SDL_QUIT:                           // time to quit
      mySDL_Quit();                          // clean up and exit
      exit(0);
      break;
    }
  }

  mySDL_Quit();
}
So what are some of the cons of this library? Mostly that the author likes to extensively use his own custom functions for things unrelated to the library. In addition, his "Fast Events" library is required to use Net2 at all (unless you want to modify the source).

Check out the Net2 Library here:
http://www.gameprogrammer.com/net2/net2-1.html