The hierarchical Driver Design has many applications on windows, but it actually started from Unix. As early as the time when Unix was a future dispute, there was no TCP/IP at that time, someone proposed "pushing a stream into another stream" for stack-based stream combination to adapt to multiple different protocols. The so-called stream is an object in the OO language, contains one or more modules. Each module has two queues (input queue and output queue) and a set of methods, such as "streaming", "data put", and "Fetch ", "service", when the bottom module of a stream is pushed to the top module of another stream, you need to call the "Push method of another stream" to connect, when data passes through a stream, it is necessary to call the service method of the stream. The flow of data in a stream is the process that passes through the queue of each module in sequence, each module can implement any strategized processing of data. The stream-mode I/O is more attractive than the pure device driver, and better reflects the meaning of the "protocol, A protocol is nothing more than a set of rules that most people follow. Its behavior is nothing more than processing data. It is a good idea to implement a protocol into a stream module, in this way, the Protocol itself can The specific devices of O are separated. A protocol stream module can be pushed to the IO driver stream module of multiple devices. On UNIX, one endpoint of a stream is a file descriptor, another endpoint is the device driver, that is, the specific device. For more information about the Unix stream, see the Unix Source Code. For more information, see the Linux terminal driver, you can also refer to my previous article about the terminal. The so-called line procedure is a protocol flow module, which can be pressed on different device drivers, it can also be directly pressed on a pair of queues to facilitate the realization of pairs of pseudo terminals. In fact, there is no network protocol in the world. The initial network is the connection between the terminal and the host, therefore, the network protocol also comes from the connection rules between the terminal and the host. However, the so-called terminal protocol is still not a peer-to-peer communication protocol, and the terminal initially only has simple processing capabilities, with the development of computer science, the original real terminal gradually became a client, and the terminal also degraded into a program on the client. The unequal communication protocol gradually evolved into a queue protocol, this is the later TCP/IP protocol family. At this time, almost all the terminals are degraded to the virtual Quasi-terminal-keyboard/display combination (data is directly transmitted between user space and kernel ), or a network Pseudo Terminal-a pair of terminals connected to the application layer protocol such as SSH or telnet (data must first enter the application layer and then return to the kernel). In either case, it will greatly benefit from the stream model, the user space's sshd and other processes read and write ptmx and the kernel space's keyboard/display driver are completely different, but they are all integrated into the stream module queue, therefore, the same line rules can be pushed into them without a doubt, achieving the same effect. Most network protocols initially achieved Remote Terminal simulation (Telnet), and finally left the terminal shadow, HTTP, FTP, SSL and so on are generated by the operation, and the network is becoming popular. Users no longer just want remote hosts to help them execute the programs they need, and then display the results to themselves-terminal methods, instead, we hope to exchange data with remote machines in a similar way. It is just the data itself-the real network.
If there is only one protocol in the world, a stream-driven hard code is enough. It is precisely because there are many different levels of protocols that need to abstract some basic things into a stream separately, then we can combine these streams to implement different protocols. The infrastructure abstracted at that time to form each independent stream is actually similar to the later OSI model and the layer logic of TCP/IP, it's just that there is no clear expression from the latter. It's not just for the network, but for any device driver, Unix recommends this stack-type stream accumulation form, each layer of the stack expresses an independent function in the device logic. This idea is a layered drive, and Unix abstracts all Io elements into files, therefore, the multi-level combination of each or multiple layers in the stack can be a single file or the entire stack can be regarded as a file. The logic control of the layers is completed through IOCTL, this method is consistent with today's windows drivers, but for network drivers, due to the existence of a large number of protocols, using this vertical combination is complicated and cumbersome and requires a lot of layers, the control on each layer is not a general administrator. As competent as developers, we need to use a block-based control method to manage network communication. Each block can be further divided or vertically controlled. In this way, in each small block, the hierarchy is clear, and the control is simple. a bsd socket is generated because many layers that are not needed but cannot be avoided, the socket uses three constraints to generate a unique local file descriptor that can be used for communication. These three constraints are at different levels. The first constraint is "domain ", for example, pf_inet (vpv4), pf_inet6 (IPv6), and pf_packet. by specifying a domain, you can select a protocol family. There are many "types" under each "Domain", such as sock_stream, sock_dgram, by specifying a type, you can select a specific protocol type in a protocol family. This type restricts the meaning of the communication, but does not provide the communication syntax, next, select a specific protocol under a specific protocol type, such as TCP and UDP, and the communication syntax is determined, so that a socket is uniquely identified, sockets do not pay attention to the layers below the semantic level of data transmission, That is to say, generally, sockets do not focus on any semantics and syntax of the link layer and physical layer. This is also one of the charm of sockets. It also becomes a heavyweight chip to defeat the stream model. The socket knows that its responsibility is communication, therefore, it clearly separates communication services and bearer services, that is, what is the concern of both parties, what is the concern of the Data bearer channel or machine, as a result, the socket no longer pays attention to the control of the underlying channel, so three parameters can determine a socket descriptor. For the stream model, because the stream only adds a stack, the quantity and nature are not fixed. Therefore, it is difficult to distinguish between the communication service and the bearer service. In the end, the entire package must be included and managed along the stack to the physical link. The above content is all about TCP/IP. When the socket was designed, there were not so many protocols. Therefore, we can see that there is another advantage of sockets, that is, scalability.
In short, sockets use a tree-like model (because many domains can share many types, they are actually a ring chart) to create communication node facilities. Although there are many nodes on the tree, but the child of a node is limited, while the stream model is a linked list. Although each stream also forms a graph, there is no horizontal relationship between nodes except the hierarchical relationship, the child of a node at a certain level is all the nodes at its lower layer. It is very complicated and difficult to control to create a communication facility only after the nature of all these flows is clarified, in this case, file descriptors are no longer synonymous with simple unification, but replace them with a mixture of confluence and traps. The final socket wins the stream model and is accepted by various operating systems, including windows...
Windows not only accepts sockets, but also the stream model concept, and accepts this idea in the field of network communication, therefore, Windows Sockets are almost perfect, not as extreme as other sockets. Windows not only implements BSD sockets, but also provides SPI similar to the stream mode to support LSP, it provides an interface for application vendors to control sockets. Note that this interface is not provided for application developers directly. Isn't the stream mode too troublesome for application developers? Let's just give them a simple accepted socket interface. What is the specific interface or the stream mode, the WSC functions provided by SPI can be used to stack their own logic to control the communication flow. Because Microsoft is always good at interface design, therefore, it is not difficult to use SPI. wscenumprotocols lists all the protocols, and then you can define a wsaprotocol_infow by yourself and install it using wscinstallprovider, wsaprotocol_infow itself contains a linked list for implementing the stream stack. Each element of the linked list is a wsaprotocol_infow. You can use wscgetproviderpath to obtain the DLL of the Protocol's specific implementation logic, this dll has a wspstartup method, which can implement send, Recv, connect, accept, and other logics. Every time the DLL completes data processing, it can call the wsaprotocol_infow chain corresponding to the DLL. The corresponding method of the dll implementation of the next wsaprotocol_infow table to continue data transmission. You can use wscwriteproviderorder to implement stream stacking in any order (in fact, it is a protocol to form a linked list ). It can be seen that the logic of LSP is consistent with that of the old UNIX stream model. SPI can be used to implement the presentation layer, Session Layer, and other non-existent logical layers. Even in the kernel mode, the NDIS driver is also layered and similar to LSP, except for implementing standard protocol stacks that are dispensable, such as filtering or encryption/Decryption mechanisms, what about the protocol stack? It is also layered! It seems that layering is the essence, while sockets are just an easy-to-use interface.
Windows implements the essence of layering, and its LSP and NDIS drivers are similar to the stream mode, but what about other operating systems? Has it completely abandoned the sub-flow of ancient UNIX? None! Mac has never been touched. Except windows, Linux and UNIX are the most widely used versions. These systems do not have the intention to design the strategized operating system-level interfaces in a unified manner, therefore, you must find the sub-layer shadow from various open source codes. OpenSSL is an example. Check whether the bio mechanism is similar to windows LSP, and it is closer to the old UNIX stream. In fact, good things will never be discarded. At the beginning, Unix abandoned the stream model only for network communication and is more inclined to socket in the sense of interfaces.
In general, the stream model is more flexible than the socket, but the socket achieves a perfect balance between flexibility and availability. The main advantage of the stream mode is that the protocol module can reuse different drivers, however, it does not involve how to implement this multiplexing, that is, it is too flexible and the management capability is insufficient. Although the protocol module can be reused, the device control part is too complex, domain, type, and Protocol cannot be combined at will. At least you will read the specifications that can be combined in advance, and the control part is also controlled by IOCTL or sockopt in a unified manner. There are not many parameters and it is easy to learn and use, in fact, UNIX is not an extreme generation, and even a good programmer needs to weigh.