Essentially, it’s just another way of inter process comunication(IPC) between tcp/ip network applications. The layered structure of the network protocol stack only decouples the complexity of communication in the application layer, which does not need to consider data loss, data duplication and transmission timeliness in the communication process. Such problems are solved by the transport layer, the application layer only focuses on messages and processing logic in the layer. Therefore, the general transport layer modules work in the system kernel to provide the same service for all processes in the system. The operating system encapsulates the transport layer and other underlying protocols and provides uniform access interfaces for the application layer. This article mainly describes how the TCP transport layer provides abstract services for the application layer, and attempts to implement a minimalist application layer protocol based on TCP, observing the TCP protocol from the perspective of the application layer.
TCP Model
TCP provides end-to-end connection service for the application layer, and full duplex communication can be achieved between the two sides. The communication data is sent and received in the form of reliable byte stream. Because UNIX systems are designed according to the everything-is-file rule, network devices are also abstracted to files, so network devices can be accessed using the common UNIX system IO. This is all that a process referring to TCP stack communication knows. As for how to ensure the reliability of data transmission, the flow control of data traffic when the network congestion happened, all these are not visible to the process.
End-to-end connection
TCP only supports communication between two processes in the network, and a connection needs to be established before the process can communicate. Typically, the two processes are client and server relationships. When a process sends and receives data, it simply reads and writes from a file descriptor bound to the network. For the system kernel, the file descriptor that establishes the connection is bound to a quad set {client IP, client TCP port number, server IP, server TCP port number}, which can uniquely identifie a TCP connection.
Full-duplex
A process that participates in communication and can send and receive data at the same time.
Byte stream
Communication data is a reliable byte stream, which means that process communication data is sent and received byte by byte according to the sort. Therefore, the application layer needs to complete the parsing and segmentation of application-layer messages.
Sequence of communication
The process implements network communication by calling the set of Socket API functions. The communication process is roughly divided into four stages: communication preparation stage, TCP connection establishment stage, data interaction stage, and TCP connection release (disconnect) stage.
Preparation
- the client mainly calls the function socket() to apply file descriptor sockfd. If the client does not call the function bind() to bind the local TCP port number, the operating system will automatically assign a temporary port number to it. Sockfd corresponds to {client IP, client temporary TCP port number}.
- the server mainly calls the function socket() to apply file descriptor listenfd. The listenfd is used to receive connection requests from unknown clients. The server must call the function bind() to bind the TCP port it is listening to, which is the well-known port number of the server process. The listen() function informs the system kernel that the listenfd is only used to wait on connection requests from unknown clients.
Connection establishment phase
- the client calls the function connect() to initiate a request to establish a connection to the server. If the TCP connection is established successfully, the file descriptor sockfd binding is a quad {server IP, server TCP port number, client IP, client temporary TCP port number}.
- the server side calls the function accept(), which blocks and waits for the TCP connection request of the unknown client. If accept() returns successfully, the return value is the file descriptor connectfd. The connectfd binding content is a quad {server side IP, server side TCP port number, client side IP, client side temporary TCP port number}.
Data interaction phase
- At this point, both ends can use UNIX standard IO functions read() and write() or use Socket function family send() and recv() to send and receive data, the client read and write object is sockfd, the server read and write object is connectfd.
Release
- When either end completes sending or receiving data, use the function shutdown() to close the “r”, “w”, or “rw” operations to the file descriptor, or use the function close() to close the “rw” operations to the file descriptor.
Example
The following is an implementation of the simple application layer communication protocol mentioned earlier in c. To simplify error handling in the code, the lib function in UNPv3 (“lib/unp.h”) is used.
Server: a “Server” process running on host S
Client: a “Client” process running on host C
The content of the request message sent by the client is a string, “request,hostname”
After receiving the request message, the server gets its own host name, and then replies it to the client, “response,< the obtained host name >”.
Client
1 |
|
Server
1 |
|
Run
Server 1
2
3
4toto@ServerOS:~$ server
Receive message from client process on 10.16.56.2: request,hostname
Receive message from client process on 10.16.56.2: request,hostname
~阻塞等待
Client 1
2
3
4toto@ClientOS:~$ client 10.22.5.3
response,guru
toto@ClientOS:~$ client 10.22.5.3
response,guru
Reference
Some more reference
- RFC2616,“Hypertext Transfer Protocol/1.1”和《HTTP The Definitive Guide》
- RFC3117,“On the Design of Application Protocols”
- RFC3205,“On the use of HTTP as a Substrate”
- RFC5321,“Simple Mail Transfer Protocol”