We fulfill power fantasies

RSS Feed Back

Give me proper networking tools on Windows

10.11.2018 21:44:09

Last week I spent multiple days creating a bad, inefficient abstraction over WSAPoll, which itself is a bad, inefficient abstraction of other functions, simply provided for UNIX compatibility by Microsoft.

The thing is, Windows has efficient, scalable methods of managing network IO, namely, IO completion ports. But it's such a pain to use in a cross-platform application. With IOCP, because you only get informed after a recv() on a socket is done, not when you can do one yourself, you must maintain unique buffers on each one of your sockets. And if your application is a cross-platform one, you basically have to make your Linux abstraction work in a similar fashion, because the socket recv() function just cannot be used the same way with both systems. (As a side note, I've built an API for async socket IO that works on both systems, using IOCP on Windows and epoll on Linux. It's called netqueue and it's included in MUTA's source code.

Linux on the other has epoll, one of the comfiest APIs I've every used. I love epoll in terms of how easy to use it is. Add a file descriptor or many to an epoll instance and just sleep on epoll_wait() until something happens, like you receive some data over the network.

I want epoll on Windows! But I can't get it, not without additional dependencies to external libraries or a lot of work.

My saving grace is that our game's servers don't need to run on Windows in release mode. The only reason the server runs on Windows is that sometimes we have to develop on it, and in such cases its handy to have the server run on the same machine with the client. So what I've done is I've wrapped WSAPoll to look a bit like epoll. It's a terrible hack and certainly inefficient, but it'll do for our purposes. Of course, features such as EPOLLET, edge-triggered behaviour, will not work on Windows (in edge-triggered mode, new events for sockets are only notified of once, not until the socket is recv()d from), and in fact even a library I found, attempting to provide epoll for Windows, didn't support said feature.

Still. I want epoll or something similar to it on Windows. Why does Win32 programming have to always be such a pain?