Recently, I came across the concept of multiplexing while studying NIO, and then I thought about the computer Network I studied in college. At that time, learning network always felt like a bunch of empty theories, because what I learned was not connected with practice. In the process of learning NIO, I felt I had a new understanding of computer network, so I decided to sort out my knowledge of network. Note that this article is an overview, not a discussion of specific protocols, but a simple model for understanding the network.

A bridge between procedures and protocols

Nowadays, the Internet is very popular. Every day on the subway, there are many people doing many things with their mobile phones, such as reading news, playing King of Glory and scrolling Douyin, all of which are using online applications. Interestingly, all web applications are based on essentially the same programming model, have similar overall logical structures, and rely on the same programming interfaces. The network is a very complex system, and what I can say here is just a scratch. My goal is to build an easy-to-understand network communication model from the programmer’s point of view.

When we talk about network communication, we’re really talking about processes on two computers exchanging information over the Internet, if we think of the network as a black box. Every web application is based on the client-server model, where the server manages certain resources and provides certain services to the client by manipulating these resources.

Roughly speaking, a process is a running program, so we now want our application to be supported by the Internet, or to communicate with the network, but we can’t directly use the standardized application protocols of the Internet, so what should we do? To answer this question, you actually need to understand the Socket described below, and in fact a more complete answer should be provided by Network Programming.

Socket

Typically, each high-level programming language has a corresponding interface or class library that developers can invoke. But the reality is that applications still need an operating system to be supported on the Internet.

For computers, the network is also an I/O device, a data source and receiver. A network card provides a physical interface to the network (what do you know about a network card? , wait for me. Data received from the network is copied from the network card through the I/O and memory bus to memory, usually via DMA. Similarly, data can be copied from memory to the network. Read my “operating system and general computer composition principle brief introduction” this article should know that the program is not directly in touch with the hardware, the program can only through the operating system to provide services, to CARRY out I/O operations. Similarly, it is necessary to call the interface provided by the operating system to obtain and send information from the network.

The TCP/IP protocol software now resides in the operating system. Because the TCP/IP protocol family is designed to run on multiple operating systems, the TCP/IP protocol standard does not specify the details of how applications interface (call) with TCP/IP protocol software, but rather allows system designers to choose implementation details about apis.

Currently, there are only a few TCP/IP apis available for application programs. The most famous one is the API defined by the University of California, Berkeley, for the Berkeley UNIX operating system, which is called the Socket Interface. Microsoft uses a Socket API in its operating system, but with a twist, we call it Windows Sockets. The interface defined by AT&T’s Unix System V version – TLI(Transport Layer Port)

We can think of sockets as interfaces between processes and transport layer protocols, as follows.

Note: processes above the socket are controlled by the application, while processes below the socket are controlled by the operating system. Therefore, whenever a program wants to communicate using the TCP/IP protocol, it must invoke the network communication interface provided by the operating system. The socket here is a relatively abstract concept, so how to understand the socket here? Why the socket here? Because sockets have other semantics in other contexts, they are also called sockets. I think the Socket here is a rule, contract, mechanism: when the program needs to use network communication, must first call the Socket interface provided by the operating system, also known as issuing the Socket system call, requesting the operating system to create a “Socket”. The effect of this call is to ask the operating system to allocate some of the resources (CPU time, network bandwidth, memory space, etc.) needed for network communication to the application process. The operating system creates a socket descriptor number (small integer) for the sum of these resources and returns this socket descriptor to the application process. After that, all network operations performed by the application process (establishing connections, sending and receiving data, adjusting network communication parameters, and so on) must use this socket descriptor.

So almost all network calls take this socket descriptor as the first parameter. When calling the network communication interface provided by the operating system, the socket descriptor identifies which resources should be used to complete the service requested by the application process.

When the communication is complete, the application notifies the operating system to reclaim all resources associated with the socket descriptor through a close call that closes the socket.

There may be some abstraction here. Generally speaking, we can understand the Socket as a contract provided by the operating system. The contract specifies some matters related to network communication.

It is natural for an operating system to have multiple network applications, so you need a table of socket descriptors, each with a pointer to the address where the socket is stored.

Different semantics of sockets

Sockets have different semantics in different contexts.

  • Semantics under TCP connections

We know that TCP regards connections as the most basic abstraction. Each SET of TCP connections has two endpoints, and the endpoints of TCP connections are sockets. According to RFC 793, a port number is concatenated to an IP address to form a socket. Therefore, the socket is represented by the IP address followed by the number of the upper end, separated by a colon or comma. Anyway, we have

Socket = (IP: port number)

Each TCP connection is uniquely identified by the socket at both ends of the communication.

  • The interface of a high-level language to access the Internet, namely an interface between the transport layer and the application layer, can also be called a socket.

Java has a class called Socket.

  • Operating system kernel and the Internet communication of the University of California at Berkeley implementation, called socket implementation.

The process of network communication

We use the TCP protocol service provided by the operating system to introduce the process of network communication.

  • The work done to prepare a socket for a connection

First, the process invokes the service provided by the operating system to create a socket, and the operating system allocates the corresponding resources to the process applying for the socket. The port number and IP address of the socket are empty after it is created. Therefore, the application process needs to bind the IP address and port number to specify the local address of the socket. In this case, the binding is also a service provided by the operating system. Invoking the binding service actually calls the IP address and port number into the created socket.

Knowing that TCP is connection-oriented, it is not enough to simply create a socket. Instead, you should invoke the listening service provided by the operating system (often referred to as LISTEN) and set the socket to a passive mode to accept service requests from customers at any time. The UDP service provides only the connectionless service and does not use the Listen service.

The application then invokes the accept service, often called the Accept service, to extract the connection request.

After calling the Accept service, there is more action to complete because the server must process multiple connections at the same time. The Java solution is multithreading, one thread for each connection. When there are too many connections, we need to change the way we think about it. This is called multiplexing.

  • Data transfer phase

After the connection is established, the client and server send data to each other.

  • Connection release phase

As we mentioned above, to create a socket is to apply for resources from the operating system. We also know that the TCP connection time can not be indefinitely connected. When the connection is closed, it is necessary to release the resources applied to the operating system.

I/O multiplexing

We know that when there are fewer clients, it is no problem to use multithreading to deal with the client connection. This model is generally called multithreading concurrency model. Threads can be called lightweight processes in a sense, so this model is also called multi-process concurrency model.

Now often also multi-core CPU, can make full use of multi-core. However, this model does not make sense. We need to create a thread for each client. Whether the client sends data or not. As the number of clients increased, the overhead became unbearable.

Let’s analyze the irrationality of this model. The server is always listening to the client’s connection. When the connection is established, the server starts a thread to handle the client’s communication regardless of whether the client sends data. Many threads are idle before data arrives, which is quite wasteful. The solution is to spare a thread to record the state of these clients. This thread is the manager. Once the connection is established, do not start the thread until the data comes, and then process the data. The advantage of this is to reduce the thread overhead. Once again, the connection is ready and the server process does not process it for the time being, whichever client data comes in. This is multiplexing, I/O multiplexing.

Select, poll, and epoll are all implementations of I/O multiplexing under Linux. Why three? Because these three appear in order. Widnows multiplexing under specific implementation for the select function (winsock2. H) – the Win32 apps | Microsoft Docs

For details, see what does IO multiplexing mean?

References:

  • Computer Networks (7th edition) by Xie Xiren
  • Understanding Computer Systems in Depth. Third edition
  • What does IO multiplexing mean?
  • Learn more about IO multiplexing