Original author of zmq/nanomsg here.<p>After all those years dealing with the problem of implementing network protocols I believe that this entire tangle of problems exists because we are dealing with something like 35 years of legacy in two different but subtly interconnected areas: concurrency/parallelism and network programming APIs.<p>The area of concurrency/parallelism started quite reasonably with the idea of processes. But then, at some point, people felt that processes are too heavy-weight and introduced threads (I'm still trying to find out who the culprit is, but it looks like they've covered their tracks well.) When even threads became too heavy-weight people turned to all kinds of callback-driven architectures, state-machine-driven architectures, coroutines, goroutines etc. Now we have all of those gand we are supposed to make them work together flawlessly, which is a doomed enterprise from the beginning.<p>At the side of network programming, BSD sockets (introduced in 1983) are the only common ground we have. They are long past their expiry date, they don't adapt to many use cases, but there's no alternative. There are more modern APIs there, but, AFAICS, none of them provides enough added value of top to become the new universal standard.<p>It should be also said that creation of new universal APIs is hindered by a host of weird network protocol designs out there in the wild. The API designer faces a dilemma: either they go for sane API and rule at least some weird protocols out or they try to support everything and end up with one mess of an API. Not a palatable choice to make.<p>Then there's the area where the two problems about interact. Originally, you were supposed to listen for incoming TCP connections, fork a new process for each one and access the socket using simple single-threaded program with no state machines, using only blocking calls. Today, you are supposed to have a pool of worker threads, listen on file descriptors using poll/epoll/kqueue, then schedule the work to the worker pool by hand. This raises the complexity of any network protocol implementation by couple of orders of magnitude. Also, you get a lot of corner cases, undefined behaviour, especially at shutdown, weird performance characteristics and I am not even speaking of the increased attack surface.<p>All in all, it's a miracle that with the tools we have we are able to write any network applications at all.<p>These days I am working on attacking the issue on both fronts. On the concurrency side it's <a href="http://libdill.org" rel="nofollow">http://libdill.org</a> -- esentially not very interesting, just an reimplementation of goroutines for C, however, what's worth looking at is the idea of "structured concurrency", a system of managing the lifetimes of coroutines in a systemic manner: <a href="http://libdill.org/structured-concurrency.html" rel="nofollow">http://libdill.org/structured-concurrency.html</a><p>On the other front, the network programming, I am trying to put together a proposal for revamp of BSD socket API. The goal is to make it possible to layer many protocols on top of each other as well as one alongside the other. It's a work in progress, so take it with a grain of salt: <a href="https://raw.githubusercontent.com/sustrik/dsock/master/rfc/sock-api-revamp-01.txt" rel="nofollow">https://raw.githubusercontent.com/sustrik/dsock/master/rfc/s...</a>