Socket calls for TCP and UDP

At the network layer, the Socket function needs to specify whether it is IPv4 or IPv6, and the corresponding settings are AF_INET and AF_INET6 respectively. In addition, it is necessary to specify whether it is TCP or UDP. The TCP protocol is based on data streams, so it is set to SOCK_STREAM, while the UDP protocol is based on datagrams, so it is set to SOCK_DGRAM.

The TCP server must first listen to a port, usually calling the bind function first to assign an IP address and port to the Socket. Why do we need a port? You must know that you are writing an application. When a network packet comes, the kernel must find your application through the port in the TCP header and give the packet to you. Why do you need an IP address? Sometimes, a machine will have multiple network cards and multiple IP addresses. You can choose to monitor all network cards, or you can choose to monitor one network card. In this way, only the packets sent to this network card will be sent to you. .

When the server has the IP and port number, it can call the listen function to listen. In the TCP state diagram, there is a listen state. After calling this function, the server enters this state, and the client can initiate a connection at this time.

In the kernel, two queues are maintained for each Socket. One is a queue where the connection has been established. At this time, the three-way handshake of the connection has been completed and is in the established state; the other is a queue where the connection has not been completely established. At this time, the three-way handshake has not been completed and is in the syn_rcvd state.

Next, the server calls the accept function and takes out a completed connection for processing. If it's not done yet, wait.

While the server is waiting, the client can initiate a connection through the connect function. First specify the IP address and port number to be connected in the parameters, and then initiate the three-way handshake. The kernel will allocate a temporary port to the client. Once the handshake is successful, the server's accept will return another Socket.

There are two listening Sockets and the Socket actually used to transmit data. One is called the listening Socket and the other is called the connected Socket .

After the connection is successfully established, both parties begin to read and write data through the read and write functions, just like writing to a file stream.

Socket program function calling process based on TCP protocol.

It is very accurate to say that TCP Socket is a file stream. Because Socket exists in the form of a file in Linux. In addition to this, there are file descriptors. Writing and reading are also done through file descriptors.

In the kernel, Socket is a file, which corresponds to a file descriptor. Each process has a data structure task_struct, which points to an array of file descriptors to list the file descriptors of all files opened by this process. The file descriptor is an integer and is the index of this array.

UDP has no connection, so there is no need for a three-way handshake, and there is no need to call listen and connect. However, UDP interaction still requires IP and port numbers, so bind is also required. UDP does not maintain connection status, so there is no need to establish a set of Sockets for each pair of connections. Instead, as long as there is one Socket, it can communicate with multiple clients. It is precisely because there is no connection status that every time you communicate, you call sendto and recvfrom, and you can pass in the IP address and port.

Maximum number of TCP connections = number of client IPs × number of client ports. For IPv4, the maximum number of client IPs is 2 to the 32nd power, and the maximum number of client ports is 2 to the 16th power, which is the maximum number of TCP connections for a single server, which is approximately 2 to the 48th power.

Of course, the maximum number of concurrent TCP connections on the server is far from reaching the theoretical upper limit. First of all, it is mainly the file descriptor limit. According to the above principle, Sockets are all files, so the number of file descriptors must be configured through ulimit first; the other limit is memory. According to the above data structure, each TCP connection must occupy a certain amount of memory. Memory, operating system is limited.

1. Multi-process mode

This is equivalent to you being a proxy, listening for incoming requests. Once a connection is established, there will be a connected Socket. At this time, you can create a child process and then hand over the interaction based on the connected Socket to this new child process.

2. Multi-threading method

Under Linux, creating a thread through pthread_create also calls do_fork. The difference is that although the new thread will create a new item in the task list, many resources, such as the file descriptor list and process space, are still shared, with just one more reference.

There is C10K, which means that if a machine wants to maintain 10,000 connections, it must create 10,000 processes or threads, and the operating system cannot bear it. If 100,000 servers are needed to maintain 100 million users online, the cost is too high.

3. IO multiplexing, one thread maintains multiple Sockets

Since Socket is a file descriptor, all Sockets targeted by a certain thread are placed in a file descriptor set fd_set, which is the project progress wall, and then the select function is called to monitor whether there are changes in the file descriptor set. Whenever there is a change, each file descriptor is looked at in turn.

4. IO multiplexing, from “sending people to keep an eye on” to “notifying when something happens”

The function that can accomplish this is called epoll. It is implemented in the kernel not by polling, but by registering a callback function. When a file descriptor changes, it will be actively notified.

This notification method ensures that when the monitored Socket data increases, the efficiency will not be significantly reduced, and the number of Sockets that can be monitored at the same time is also very large. The upper limit is the maximum number of file descriptors defined by the system and opened by the process. Therefore, epoll is called a powerful tool to solve the C10K problem.

This article is a study note for Day 13 in September. The content comes from Geek Time's "Internet Protocol". This course is recommended.

Guess you like

Origin blog.csdn.net/key_3_feng/article/details/132865034