I have been using a home-grown continuous integration system based on a hacked version of CruiseControl.Net since 2007. Whilst it’s not perfect, it works, and I have quite a bit of custom tooling that builds configurations for it for various client projects and builds of various versions of The Server Framework.
TL;DR
By exporting the configuration of Visual Studio as a vsconfig file you can create a custom installation with specific tools in a stand-alone directory structure that can be referenced by build tools, and you can then link specific revisions of code to specific versions of Visual Studio so that they ‘always build’, even if the installed compiler is incompatible.
I’ve been playing around with the low-level access to the Windows networking stack that is provided by \Device\Afd. This provides a ‘readiness’ interface rather than the ‘completion’ interface provided by traditional IOCP designs. I’ve been meaning to do some comparative performance tests, much in the same way that I did for my investigations of the RIO API, but I’ve been too busy.
Instead, what has happened is that the AFD code has made its way into the version of The Server Framework that I’m using with my Online Game Company client.
I’ve been cleaning up a continuous integration build system for my cloud gaming client’s server system. The codebase is pretty big, and my build system on Windows is pretty rubbish but works… It has been getting slower and slower due to how I build the system, and I wanted to make it faster. Whilst doing this, I ran into a Visual Studio error message that I hadn’t seen before, and it took me a while to work out what was going on…
Last time I looked at way of using \Device\Afd to perform individual socket polling for readiness. This differed from the previous approach to using \Device\Afd, which batched up the sockets and issued a single poll for multiple sockets.
The individual socket polling approach appeals to me as it would appear to scale more easily, and putting together an echo server that supports multiple connections is now much easier. It doesn’t map as well to the way other operating systems do things though, so if that’s your primary goal, then you’re probably better off continuing with the ‘set of sockets’ approach.
Recently, I’be been exploring socket readiness notifications on Windows using the \Device\Afd interface. My initial forays into this were from a Linux epoll direction as the use of the \Device\Afd API provides a similar interface to the epoll API and makes it possible to build something almost the same on Windows which can help when writing cross platform code.
I’d got to the point where I had a simple client and server working nicely and had taken a pause before the next step which was to add support for multiple sockets.
I’ve just had to deal with a situation where Windows 11 Explorer crashes and restarts every time I browse to a particular directory. The directory contained the source to my AFD code and I somehow managed to guess at the cause and fix the offending file…
The problem was that I had some Visual Studio sln files checked in to a git repository and at some point git had changed the line ends from windows \r\n to unix \n.
For a while now I’ve been playing around with the low-level access to the Windows networking stack that is provided by \Device\Afd. Recently I had a comment from a reader, Matt James, who pointed me in the direction of his work over at https://github.com/Emjayen/napi which does a lot more with the \Device\Afd interface than I have. It’s well worth checking out.
This code includes, as reference, a set of NT Native API headers from the Process Hacker project, which in itself is interesting stuff, but Matt’s code goes far beyond my megre investigations and provides enough information to produce a full featured network API that appears to be able to everything you might need through the \Device\Afd interface.
The only difference between a client and a server is the way in which the connection is established. For a client, you create a socket and call “connect” on it. For a server, we have a socket that is “listening” for connections, “accepts” new incoming connections and returns a socket that is then indistinguishable from a client connection.
In the past, I’ve created bad abstractions at this point. A socket connection and a listening socket are both represented by the operating system API as the same type, and the only differences are the calls that you make on the type.
Now that I have a reasonably easy to use event-driven socket class I can start to use it. The first thing to build is a simple client. This will connect to a server and expect that server to echo anything that is sent to it. The client will send data and read it back and compare it with what it sent.
A simple, single-threaded, client Last time, I put together a tcp_socket object that made it easier to work with the \Device\Afd interface that I’ve been playing with.
I’ve been investigating the ‘sparsely documented’ \Device\Afd interface that lies below the Winsock2 layer. Today I use a test-driven method for building some code to make using this API a little easier.
Using the API In my previous posts on the \Device\Afd interface I focused on exploring and understanding the API itself. Since it’s ‘sparsely documented’ I used unit tests to explore and record my findings. This has left me with some code that is easy to come back to and pick up, which is lucky since it’s been quite a while since I last had some time to tinker with it.