Find downloads at the bottom of this post!
I wanted to make an application in C++ using sockets and threads to test myself and get familiar with C++. It took me a couple of days and this is what I came up with.
It is an application to easily transmit a file in a LAN.
It works by running “server ” in a CLI, this will start the server which will advertise its presence and transmit its file to anyone who connects to it. By “advertise” I mean it will open a UDP socket to listen for incoming broadcasts from clients.
On another computer you run the client from a CLI which will query for file servers in the LAN by broadcasting a UDP packet to the file server UDP port, present its findings and you can then choose which file to download.
I first started working with sockets in Visual Basic 6 when I was 12 years old. I started out creating a chat application, which at that point took me weeks and never worked properly.
In the past couple of years I’ve been diving back in to it, by creating a lot of unfinished multiplayer games with .NET(C# and VB) and GameMaker. I love LAN games and I really wish there were more of them, but it seems I am not patient enough to create them, at least not alone.
I’m currently taking a course in networking in which we’ve implemented a chat application in Python. It is extremely easy to set up sockets in Python and can even be accomplished by running the Python environment in a terminal, which makes it really cool for debugging.
I’m really eager to try out network programming in Unity3D as it seems completely different from what I am used to; it uses RPCs as far as I can tell.
I use the Boost library to achieve a cross platform implementation of sockets and threads. This did not work out. I spent hours trying to compile the project with MinGW, I eventually gave up and tried with Visual Studio which I got working rather quickly. But then the applications started crashing and acting weird because apparently sockets are only thread safe in Boost if you’re using Linux and some other bugs I don’t have the patience to uncover cropped up, like the client randomly appending characters to filenames and ports when splitting them. I successfully sent and received files from Windows<->Linux and Windows<->Windows, albeit with crashes, but that’s the best I can do without rewriting the entire thing. And it’d probably be easier to just write a Windows specific solution rather than using Boost. But for some reason it still felt really awesome sending a file from a Linux laptop to a Windows desktop.
I haven’t put much weight on the structure of the code and spent most of the time digging around in Boost documentation. Right now it works, but it is really cluttered and a lot of stuff could probably be removed, since it is only there because I thought it would work at some point in time, but it didn’t and I am too lazy to refactor the code, since this was just a test.
I only wrote one file per executable, no header, no classes, no nothing(so a lot of something, I guess). I commented every section of the code to make it easier to understand for people wanting to learn.
I also learned about static linking from making this project. It’s something I guess you don’t know about when you’ve grown up with IDEs and very high level languages which handle most of the linking hassle for you. But apparently you can just put whatever libraries you’re using in the compiled executable, which will make it larger but also self contained, i.e. no darn dependencies!
Dependencies have always been a bitch for me; I couldn’t show off my first games when I was a kid since they would only run on my own PC(GameMaker was a dream come true). Sometimes I find it hard to find dependencies and package them properly; to this day I still don’t know how to deploy MonoDevelop/GTK projects short of just including the entirety of MonoDevelop in the package, which really sucks since I wanted to use it for a Linux/Windows game. I wonder how Unity3D does it?
Ideas for expansion
- Multiple file servers on one host: You could alter the server so that if the UDP port is taken it will send its filename and endpoint to the UDP port so the currently running fileserver can advertise its presence for it. You could also just make a single fileserver handle more files, but that would make it more complicated and defeat the purpose of the project, i.e. easy file transfer.
- More customizability: Most of the options are hardcoded; port numbers, buffer size, etc., simply because I was too lazy to handle arguments.
Without further ado: