Have Sockets Run Their Course? 230
ChelleChelle writes "This article examines the limitations of the sockets API. The Internet and the networking world in general have changed in very significant ways since the sockets API was first developed in 1982, but the API has had the effect of narrowing the ways in which developers think about and write networked applications. This article discusses the history as well as the future of the sockets API, focusing on how 'high bandwidth, low latency, and multihoming are driving the development of new alternatives.'"
Re:whats really needed... (Score:5, Informative)
You mean like this? http://en.wikipedia.org/wiki/Unix_domain_sockets
Open Transport, Part II (Score:5, Informative)
Been there, done that. Apple (once again) had a great implementation of an alternative technology, that it finally abandoned when it didn't feel like fighting any more.
Open Transport [wikipedia.org] (the PPC stack used in the Classic Mac OS) was fast, efficient, and cool. And based on the STREAMS [wikipedia.org] methodology, the only real competition to Berkeley Sockets.
Choice is good, mmmkay?
Which sockets API? (Score:5, Informative)
Structured Stream Transport (Score:5, Informative)
BSD sockets have a limitation of only a single stream at a time (for example, if you are loading a website over HTTP and you get stuck loading a huge image, you have no choice but to open up another socket connection or else wait). They are also stuck around the paradigm of only supporting byte streams, which means that users are always forced to write the same code over and over to create packet headers or delimited messages.
I would highly recommend checking out Structured Stream Transport [mit.edu]. I'm not from MIT and I wasn't entirely satisfied with their sample implementation, but the paper is really insightful and explains how you can develop basically a smarter version of TCP that is both more efficient and also more flexible. And I'm sure there are other systems being developed with similar ideas in mind.
We definitely need to keep bsd sockets, if not just because I'm a regular user of netcat :-p, and also because they are what allow the creation of more advanced protocols, but I don't think most applications should still be using such low-level protocols today.
STREAMS? (Score:2, Informative)
Macs used STREAMS from system 7.5.2 onwards. Was kind of sad to see that go away with the switch to OS X.
Re:Structured Stream Transport (Score:5, Informative)
No matter how much abstraction you pile on top to open multiple streams, automatically add headers, communicate a fix message size to avoid in-band delimiters, etc., you'll still have to send all those messages over linear octet streams when using TCP.
Now you could choose not to use TCP -- UDP lets you send non-linear messages of arbitrary size without delimiters. And there may be other newer, better options available as well. But you can do both TCP and UDP (as well other other comm types) using the same sockets API.
Re:Structured Stream Transport (Score:5, Informative)
BSD sockets have a limitation of only a single stream at a time (for example, if you are loading a website over HTTP and you get stuck loading a huge image, you have no choice but to open up another socket connection or else wait).
No it doesn't. This is a limitation of TCP. You could just as easily use a different protocol (e.g., SCTP) with sockets.
Re:SCTP an interesting example (Score:4, Informative)
So use a wrapper, like sctp_send [die.net] from libsctp. There's no reason the kernel proper has to export these interfaces.
Re:wrong (Score:5, Informative)
Windows' solution is pretty nice. You can pass a pre-created socket handle to accept_ex, which automatically accepts an incoming connection using that socket handle, so that you don't have to use two system calls (select and accept). You can also pre-accept multiple sockets, instead of having to make the system calls under load.
Sockets can also be closed with a "re-use" flag, which leaves the handle valid and saves making a system call to create another.
You then associate the sockets with an "IO completion port", which as best as I can tell is a multithreaded-safe linked list for really fast kernel to user program communication. To receive from the socket you make an async receive call, giving a pointer to a buffer to receive into.
Whenever data is received on those sockets (and has had a corresponding async request made for it already) the kernel automatically queues the socket handle to that linked list. If you associate a socket with the completion port before you accept a connection with it (i.e. you're using acceptex) it also triggers when the socket accepts a connection.
In the user code, you run multiple threads listening on the completion port (you can also use the completion port in the thread pooling API, which runs two threads to each cpu core by default). When a message arrives from the kernel, the most recently finished thread wakes and processes the received data, which will already be in the user-space buffer you provided in the original receive call.
If all threads are busy and there are messages in the completion port they will bounce right off of the completion port, picking up the next bit of completed IO they need to process without making a system call.
Unix always had it (Score:5, Informative)
You mean, like pipes [wikipedia.org]?
Re:Open Transport, Part II (Score:5, Informative)
Plan 9 (Score:2, Informative)
Already does that.
Re:Really... (Score:1, Informative)
You think the "or worse" is a joke? Apparently you didn't read the link:
Re:Open Transport, Part II (Score:4, Informative)
Sure it was cool how you could push and pop drivers (say you wanted a different line discipline) but please tell me how it prevented any copies? The AT&T implementation also had two extra context switches.
This is what was bad about STREAMS:
In early implementations there was no notion of multithreading so a bad thing happened later. There was a time when the STREAMS drivers and demultiplexers assumed single threaded so the kernel had to pass off to a single worker thread in the kernel everything STREAMS related. So yo had some big iron box of the time with say four processors and IO performance was just balls until the STREAMS drivers were rewritten. But then you still had that worker thread around, so one thing was that those were broken out, so there was an extra two thread switches there. Then they did some stuff variously called something like Fast STREAMS where the fast paths would not switch. So all this optimization work went in to making STREAMS fast and they were still slow. It turned-out that the reason for that was due to the complexity of the STREAMS subsystem and all the layering that caused so many extra function calls per driver. STREAMS have largely been relegated to legacy and conformance at this point.