Networking Is Not About Sockets

Scott Woods
8 min readNov 20, 2024

--

Computer Networking vs Human Conversation

Photo by Ben White on Unsplash

Networking has exploded over the last decade or so. There was a time when the business pundits declared confidently that commerce would never happen over infrastructure as unruly as the Internet. Now, it becomes more and more difficult to manage a modern life without resorting to your smartphone. In the best cases, it takes a few minutes with an app to resolve your latest need, perhaps with a few additional minutes to “like” everything in the user experience survey. As a solution to the moment, that is an amazing thing. Where are those pundits now?

Underneath every slick user experience are several layers of software, from the lowest level that interfaces with the physical world, through to the software that transfers messages like GetUserAccount between the app and the website. This layering is captured in the OSI model. Without the development of strong standards in the different layers there would not be the networking environment (that spans multiple products from multiple vendors) required to support a device such as the smartphone.

In general, each layer implements its own abstractions and maintains behavioural contracts with the layers above and below. With some formalized exceptions, layer jumping is discouraged; layer 7 (application) should not make reference to abstractions at layer 4 (transport). In more concrete terms, applications should not be opening sockets.

Application or app has different meanings in the different contexts, i.e. within the OSI model, within the smartphone eco-system and within general software development. Unless stated otherwise, application is typically a reference to the OSI meaning and app refers to software installed on smartphones. Process refers to a platform instance of an executable image.

To this day the correct layering is still in dispute (OSI vs Internet suite) and the OSI model is abstract rather than concrete. The protocol wars and the lack of concrete examples are convenient explanations for why so many modern applications break the OSI layering rules. If applications are not supposed to open sockets (i.e. a transport) to send requests (i.e. between applications) then what exactly should they be opening? If an amazing user experience can be delivered by an instance of one such unprincipled app then why should the next app not benefit from that success story?

This document proposes that something is missing from the software architectures adopted for networking. This relates to the internal structuring of networking processes and also a specific entity within that structuring. It uses an analogy to present the typical approach to networking in a different way and expose the underlying issues.

Lastly, there are a set of links to introductory documents and a software library. The software library is a concrete implemention of a networking framework, a framework that defines the internal structure of networking processes and delivers that missing piece. Follow the material in the documents and build yourself a running example of fully asynchronous, distributed networking with around a dozen shell commands. Without a socket to be seen.

Human Conversation

A conversation between two people can be compared to the exchange of messages between two networking processes. Both can be viewed as layer 7 exchanges of application messages, sending and receiving information in the service of some higher purpose, e.g. gossiping.

A simple layering of human conversation might look like;

  • larynx and ears
  • speech and hearing centres
  • consciousness

There are similarities to the OSI layering. Larynx and ears operate at the physical layer, speech and hearing probably at the presentation layer, and consciousness at the application layer.

Within this layering, conversation is between two conscious entities; it would be strange to talk to an ear without regard to its owner. Abstractly that would be equivalent to an application that opens a socket and starts sending messages over the associated transport. Messages received over such transports effectively terminate in the listeners ear, when what is tacitly expected is that they will be received by the listeners consciousness. A cruder expression of this issue is that speaking to a detached ear and expecting a response is silly (and beyond disturbing).

Acknowledgement that this issue exists is present in concepts such as request ids and channel ids. These concepts tack information onto the messages that pass between a client and server, to support concurrency of requests and multiplexed messaging, respectively. In both cases there is a separation between the receiving socket and where the messages are terminating, i.e. in a request manager or channel manager. Messages are no longer terminating in the ear.

While both concepts introduce an additional layer, we are now talking to something resembling the OSI networking layer. When the layering says we need something resembling an application.

Networking Without Sockets

What happens if we dispense with request ids and channel ids and instead adopt object ids?

Consider a runtime framework that allows networking processes to register objects, resulting in a unique object id. The objects have a standard send method available to them that accepts a message and an object id as parameters. The method takes care of delivering the message to the intended object.

An implementation of such a framework involves many technical details that are outside the scope of this document. However, it may be helpful to think of an object as a message loop with a unique id.

A simple server will register a single object that establishes a network listen. All messages arriving over connected clients will be routed directly to the registered object. A matching client will register a single object that initiates a network connect. Once connected the client has the object id available for the remote object, and can send directly to that id.

This is networking without sockets. By starting with an object id rather than a request or channel id, applications are now talking to applications (i.e. objects are talking to objects) as the OSI always intended.

Benefits Of An Object Model Framework

Adopting an object model is not just for the sake of matching an abstract model. There are significant concrete benefits.

Clarity of networking source code is improved. Removing details associated with lower levels of the OSI model (e.g. sockets) leaves behind the application messages and the processing of those messages — which is what the source code is actually about.

For the send method described in the previous section, it is a trivial matter to add the object id for the sending object to the header that is already travelling with the outbound message. Logically speaking, this is a return address. This gives every receiver the ability to respond to the correct sender.

There are several messaging idioms available to the object developer. An object may receive a message and immediately reply — a shorthand for a send to the return address received with the message. An object may immediately forward that message to another object, perhaps to distribute load. That original return address is retained, preserving the ability for the receiving object to respond to the correct client.

Object ids are also portable and can be included in messages as normal items of data. A server can create a dictionary of named object ids that refer to different objects within the server, and then send it to a client. The client subsequently has name access to each of the individual remote objects.

The nature of object ids allows for a much richer relationship between a client and a server. As messages are sent and received, and object ids are shared across the transport, multiple concurrent exchanges can develop between distinct objects in the respective processes. This delivers concurrency of requests and multiplexed messaging without the need for request ids and channel ids.

A framework provided as a library saves the developer from writing their own version of message handling, i.e. a custom networking framework. In support of this claim consider the following. There is always a line of code where inbound messages become fully formed — they are no longer blocks of bytes or fragments of JSON. There is also another line of code where true application processing of a message begins.

Networking frameworks are the machinery in between these two points. Frameworks based on request ids or channel ids are partial solutions in that they do not deliver messages to the latter point. Unless you are satisfied with writing code that mixes the decoding of inbound messages and true application processing, you will need a networking framework. If you have developed your own then the question is whether yours is better.

To exist in that space between socket operations and application activities, a networking framework must be asynchronous. Events are continuously dropping down from the application level and pushing up from the transport level. The framework must reconcile these event streams and remain responsive, at all times. It follows that application objects will be expected to behave in an asynchronous manner. For those who believe that networks are an inherently asynchronous place, this will be met with tacit approval. A fundamentally asynchronous environment facilitates advanced networking features, performance, scalability and responsiveness.

At the highest levels an object-based framework allows networking processes to operate as containers for one or more objects (i.e. OSI applications). A single networking process may contain;

  • a single listen routing to a single server object,
  • or it might contain multiple listens routing to the matching number of server objects,
  • or it might contain multiple listens routing to a single server object.

It becomes possible to compose processes in a manner that is optimal to the operation of the broader system.

Summary

The analogy of human conversation was used to illustrate a common lack of a networking framework. Request ids and channel ids — and the underlying concepts — were introduced as solutions to this issue. A case was made that these solutions do not go far enough and the object model was presented as the more appropriate solution.

From a developers point of view, a gulf exists between the transport and application layers of the OSI model. In concrete terms this is an area demarcated by platform networking services at one end (e.g. the sockets library) and the lines of application source code at the other end. While the OSI model has been around for a long time, no standard for structuring of networking processes has emerged as the best-of-breed. Which has facilitated something of a Wild West.

RPC and HTTP have had strong influence over the evolution of networking software. While HTTP has proven itself over decades it is a protocol designed to move materials between a website and a browser. With the lack of a solution for more generic networking, to some extent RPC and HTTP have assumed squatting rights. Code reuse is commendable but it is accurate to state that not everything on a network is a website.

For demonstration of the object model, refer to the following links. These are a series of tutorials that construct a server, a client, a server that connects to supporting servers and a server that implements load management.

The Ansar networking library provides the implementation of the networking framework. Documentation is available from the linked page.

--

--

Scott Woods
Scott Woods

Written by Scott Woods

Tried a few things and one of them happened to be coding. Still trying after 30-plus years. So much to do. Bikes and beaches when I cant look at a screen.

No responses yet