A simple C++/SDL_net chat server & client rewritten

Back in January this year I was due to be teaching some diploma level programming (roughly equivalent to the UK A/S level for any Brits), and part of that had to deal with network programming with sockets and stuff, so I duly did my research and put together a simple chat server and client in SDL_net. And then my classes changed and I got moved on to teach other stuff. I wasn’t too upset though – I’d learnt a lot, and I’d put up the code to help people out who might be in a similar situation, so it was all good.

But now in November I’m back on programming duty, so I dug up my code, looked it over, and thought Naah – I can’t use that, it’s unweildy, and complex, and it would be a real pain to try to re-use the code. So I’ve gone back to the drawing board and refactored it all into something I hope is a lot more palletable and both easy to use and re-purpose. In effect, I’ve refactored it into two wrappers which now consist of a ServerSocket class and a ClientSocket class.

Check it out…

Cross Platform Socket Server and Clients
Cross platform socket connectivity? That'll be a yes, then...

Socket Server

The old chat server was 250 lines, it’s now down to 77:

Socket Client

And the old chat client was 313 lines, which is now down to 83:

On top of all this we have try/catch exception handling, a nice encapsulated & easy to work-with/modify/extend design and debug flags to control whether the client/server should be verbose or run silently. Obviously the chat client itself can’t run completely silently – you wouldn’t be able to read the messages being sent back and forth! – but when debug is off it only ever outputs anything when it receives a message or when the user enters messages to send, so it’s pretty darn quiet.

Oh, and it now comes in Linux and Windows flavours =D

Overall I’m really happy with it – it’s taken a few days to properly redesign and test (not to mention the issues involved with porting to Windows) – but I think the next time I need to do some socket stuff with C++ I’d be able to grab this code, make whatever modifications I need and get something up and running in no time.

Awthome! =P

Download links

Notes on Building for Windows

The windows client and server projects have some important tweaks made for them to compile, and it’s worth mentioning what they are:

  • The solution (which contains two projects) comes comes with a copy of the SDL and SDL_net libs and headers all merged together in the SDL folder (well, there are separate libs and include folders, but all the headers from both are in the include folder and all the libs from both are in the libs folder).
  • Each project has the following libraries linked in: SDL.lib, SDLmain.lib and SDL_net.lib, these libraries point to…
  • SDL.dll and SDL_net.dll which are in the solution’s Debug folder, so you can compile and build from Visual Studio, BUT you’lll need to copy these two dll files into the same folder as the SocketServer-Rewritten.exe or SocketClient-Rewritten.exe folders to run the executables “standalone” in other locations as opposed to build-and-run-from-visual-studio style!
  • The projects are defined as console applications, and because SDLmain.lib defines the main function as int main(int argc, char *argv[]) and not just int main() you MUST keep the definition of main in-line with the SDLmain.lib definition.
  • Finally, the projects will only build successfully in debug mode. Why? I’ve no idea. If you know how to fix it then go for it!

A Simple C++/SDL_Net Chat Server & Client

Update – Nov 2011: I’ve refactored this code into something significantly easier to work with, modify and extend – so you should probably try this instead: http://r3dux.org/2011/11/a-simple-csdl_net-chat-server-client-rewritten/.


I was due to be teaching some network programming in the new term, so I thought I’d try to find the simplest library for cross-platform socket programming and knock up some examples that I could teach from. The trouble is, there are lots of different socket libraries… Lots and lots. So I did a bit of investigating and came up with the following:

Library Good Points Bad Points
Boost ASIO
  • The real deal – a world-class, well documented socket library
  • Comprehensive – you can do absolutely anything with it
  • More complicated than I’d like for the level I’m teaching at – I’m not convinced they’ll get it
  • You need to include the boost library in each project, which makes each project big (like 60MB+ big)
C++ Sockets Library
  • Lots of documentation
  • Appears to be very solid from all accounts
  • I couldn’t get it to play ball!
SDL_net
  • Pretty small
  • Works without you having to jump through too many hoops
  • Decent level of abstraction without the need to mess about with too much C (as opposed to C++) stuff
  • Does not require SDL – SDL_net can be happily used standalone
  • Good documentation available at:
    http://www.libsdl.org/projects/SDL_net/docs/index.html
  • You do still need to transfer strings to char array pointers
  • Resolving hosts and IPs puts the details in Network Byte Order (i.e. Big Endian) numbers, which you then have to jump through hoops to retrieve as human-readable values, so you end up doing stuff like hacking a unsigned 32-bit number into an array of four 8-bit numbers to get the dot-quad IP address etc.
NetLink Socket Library
  • Small!
  • No documentation at all (that I could find), which could be because…
  • …netlink is already the name of a *nix socket mechanism which transfers data between kernel-space and user-space – why the hell would you name your C++ socket library with a name which is already used for a different type of socket communication? Fail.
SimpleSockets (now defunct)
  • ?!?
  • Surprisingly for a library called SimpleSockets, not that simple – lots of memset and memcpy stuff needed

In the end I chose SDL_net as teh winnah, as I’d already done some SDL stuff with the class previously (before switching to GLFW to minimise code-bloat), and I managed to get SDL_net up and communicating pretty easily. So, for the next couple of days I put together some simple client/server examples, culminating in the code you’ll find below, which is a (very) simple IRC-esque chat server.

Have a look – you can tell what it’s doing from the output in the windows:

SDL_net Client-Server Example
The server is in the middle, the clients connect in, and chat commences (click for larger, more legible version)

Although I’ve written this code in Linux, as SDL_net is cross-platform, this code should be cross platform – only there are two tweaks you’ll need to make for it to work in Windows: I’ve used some custom kbhit and getch functions to check for a keypress and read what key was pressed, if one was. These functions come natively with Windows, so you should use the native versions and strip the custom ones out.

With those small changes made this should work fine in Windows – but if it doesn’t please feel free to fix it yourself and send me the changes you made :)

As the code for all this is a couple of hundred lines for each for the client and server I’ve put all the source after the jump. Part of the reason it’s so large is that I’ve commented it to the hilt (no really, I’ve gone to town on it – even by my exceptionally verbose standards) as it was originally meant to be a teaching aid. Also, I’ve also left a lot of commented-out debug code in there, so you can uncomment it if you’d like to see exactly what’s going on behind the scenes.

Anyways, I hope this is of use to someone starting off socket programming with SDL_net – and if you have any issues or such please feel free to sling a comment in the article and I’ll do my best to help out.

Cheers!

Continue reading A Simple C++/SDL_Net Chat Server & Client