"Everything is Socket!"
Although the words are a little exaggerated, but the fact is, nowadays network programming is almost always used sockets.
-- I feel that I am actually working on programming and open source projects.
We understand the value of information exchange, how to communicate between processes in the network, such as how do we communicate with the web server when we open the browser to browse the web every day? When you use QQ to chat, how does the QQ process communicate with the QQ process of the server or your friend? These have to rely on socket? So what is a socket? What are the types of sockets? There are also basic functions of sockets, which are all intended to be introduced in this article. The main contents of today are as follows:
1. How do you communicate between processes in the network?
2. What is Socket?
3, the basic operation of the socket
3.1, socket () function
3.2, bind () function
3.3, listen (), connect () function
3.4, accept () function
3.5, read (), write () function, etc.
3.6, close () function
4, TCP three-way handshake in the socket to establish a connection
5, TCP four-way handshake release connection in the socket
6, an example (practice)
1. How do you communicate between processes in the network?
There are many ways to communicate locally (IPC), but they can be summarized in the following four categories:
Messaging (pipe, FIFO, message queue)
Synchronization (mutuals, condition variables, read-write locks, file and write record locks, semaphores)
Shared memory (anonymous and named)
Remote procedure call (Solaris Gate and Sun RPC)
But these are not the themes of this article! What we want to discuss is how to communicate between processes in the network? The first problem to solve is how to uniquely identify a process, otherwise communication is impossible! Locally, a process PID can be used to uniquely identify a process, but this does not work in the network. In fact, the TCP/IP protocol family has solved this problem for us. The "ip address" of the network layer can uniquely identify the host in the network, and the "protocol + port" of the transport layer can uniquely identify the application (process) in the host. In this way, the triplet (ip address, protocol, port) can be used to identify the network process, and the process communication in the network can use this flag to interact with other processes.
Applications that use the TCP/IP protocol typically use an application programming interface: UNIX BSD sockets and UNIX System V TLI (already eliminated) to enable communication between network processes. At present, almost all applications use sockets, but now it is the Internet age. Process communication in the network is everywhere. This is why I say "everything is socket".
2. What is a Socket?
Above we already know that the process in the network is communicated through the socket, then what is the socket? Sockets originated in Unix, and one of the basic philosophies of Unix/Linux is "everything is a file", which can be operated with the "open open -> read/write write / read -> close close" mode. My understanding is that Socket is an implementation of this mode, socket is a special file, some socket functions are the operations (read / write IO, open, close), these functions are introduced later.
The origin of the word socket
The first use in the networking field was discovered in the document IETF RFC33, published on February 12, 1970, by Stephen Carr, Steve Crocker, and Vint Cerf. According to the American Museum of Computer History, Croker writes: "The elements of a namespace can be called socket interfaces. A socket interface forms the end of a connection, and a connection can be completely defined by a pair of socket interfaces. The Computer History Museum added: "This is about 12 years before the definition of the BSD socket interface."
3, the basic operation of the socket
Since the socket is an implementation of the "open-write/read-close" mode, the socket provides the function interface for these operations. Let's take TCP as an example to introduce several basic socket interface functions.
3.1, socket () function
Int socket(int domain, int type, int protocol);
The socket function corresponds to the opening operation of a normal file. The normal file open operation returns a file descriptor, and socket() is used to create a socket descriptor that uniquely identifies a socket. This socket description word is the same as the file description word. It is used in subsequent operations, and it is used as a parameter to perform some read and write operations.
Just as you can pass different parameter values ​​to fopen to open different files. When creating a socket, you can also specify different parameters to create different socket descriptors. The three parameters of the socket function are:
· domain: The protocol domain, also known as the protocol family. Commonly used protocol families are AF_INET, AF_INET6, AF_LOCAL (or AF_UNIX, Unix domain socket), AF_ROUTE, and so on. The protocol family determines the address type of the socket. The corresponding address must be used in the communication. For example, AF_INET determines the combination of the ipv4 address (32-bit) and the port number (16-bit). AF_UNIX determines an absolute path. Name as the address.
· type: specifies the socket type. Commonly used socket types are, SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_PACKET, SOCK_SEQPACKET, etc. (What are the types of sockets?).
· protocol: As the name suggests, it is the specified protocol. Commonly used protocols are IPPROTO_TCP, IPPTOTO_UDP, IPPROTO_SCTP, IPPROTO_TIPC, etc., which correspond to TCP transport protocol, UDP transport protocol, STCP transport protocol, TIPC transport protocol (this protocol will be discussed separately!).
Note: The above type and protocol can be combined at will, such as SOCK_STREAM can not be combined with IPPROTO_UDP. When the protocol is 0, the default protocol corresponding to the type type is automatically selected.
When we call a socket to create a socket, the returned socket description word exists in the address family (AF_XXX) space, but does not have a specific address. If you want to assign an address to it, you must call the bind() function, otherwise the system will automatically assign a port randomly when you call connect() and listen().
3.2, bind () function
As mentioned above, the bind() function assigns a specific address in an address family to the socket. For example, corresponding AF_INET, AF_INET6 is to assign an ipv4 or ipv6 address and port number combination to the socket.
Int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
The three parameters of the function are:
Sockfd: The socket descriptor, which is created by the socket() function and uniquely identifies a socket. The bind() function will bind the descriptor to a name.
Addr: a const struct sockaddr * pointer to the protocol address to be bound to sockfd. This address structure differs according to the address protocol family when the address is created by the socket. For example, ipv4 corresponds to:
Struct sockaddr_in {
Sa_family_t sin_family; /* address family: AF_INET */
In_port_t sin_port; /* port in network byte order */
Struct in_addr sin_addr; /* internet address */
};
/* Internet address. */struct in_addr {
Uint32_t s_addr; /* address in network byte order */
};
· ipv6 corresponds to:
Struct sockaddr_in6 {
Sa_family_t sin6_family; /* AF_INET6 */
In_port_t sin6_port; /* port number */
Uint32_t sin6_flowinfo; /* IPv6 flow information */
Struct in6_addr sin6_addr; /* IPv6 address */
Uint32_t sin6_scope_id; /* Scope ID (new in 2.4) */
};
Struct in6_addr {
Unsigned char s6_addr[16]; /* IPv6 address */
};
· The Unix domain corresponds to:
#define UNIX_PATH_MAX 108
Struct sockaddr_un {
Sa_family_t sun_family; /* AF_UNIX */
Char sun_path[UNIX_PATH_MAX]; /* pathname */
};
·
· addrlen: corresponds to the length of the address.
Usually the server is bound to a well-known address (such as ip address + port number) when it is started, which is used to provide services, and the client can connect to the server through it; the client does not need to specify, and the system automatically assigns a port number. Combined with its own ip address. This is why the server side usually calls bind() before the listen, and the client does not call it. Instead, it is randomly generated by the system when connect().
Network endian and host endian
Host endian is the big endian and little endian mode we usually say: different CPUs have different endian types. These endianes refer to the order in which integers are stored in memory. This is called the host order. The definitions of the standard Big-Endian and Little-Endian are as follows:
a) Little-Endian means that the low byte is discharged at the low address end of the memory, and the high byte is discharged at the high address end of the memory.
b) Big-Endian means that the high byte is discharged at the low address end of the memory, and the low byte is discharged at the high address end of the memory.
Network byte order: The 4-bit 32-bit value is transmitted in the following order: first 0 to 7 bits, then 8 to 15 bits, then 16 to 23 bits, and finally 24 to 31 bits. This order of transmission is called big endian. Since all binary integers in the TCP/IP header are required to be transmitted in the network in this order, it is also called network byte order. Byte order, as the name suggests, is the order in which data of one byte type is stored in memory, and the order of one byte of data has no order.
So: When binding an address to a socket, first convert the host endian to a network endian, rather than assuming that the host endian is the same as the network endian using Big-Endian. Because this problem has caused a bloody case! Because of this problem in the company project code, it has caused a lot of inexplicable problems, so please remember not to make any assumptions about the host byte order, be sure to convert it into network byte order and then assign it to the socket.
3.3, listen (), connect () function
If as a server, listen() is called after listening to socket() and bind(). If the client then calls connect() to make a connection request, the server will receive the request.
Int listen(int sockfd, int backlog); int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
The first parameter of the listen function is the socket description word to be listened to, and the second parameter is the maximum number of connections that the corresponding socket can queue. The socket created by the socket() function defaults to an active type. The listen function turns the socket into a passive type and waits for the client's connection request.
The first parameter of the connect function is the socket description word of the client, the second parameter is the socket address of the server, and the third parameter is the length of the socket address. The client establishes a connection to the TCP server by calling the connect function.
3.4, accept () function
After the TCP server calls socket(), bind(), and listen() in turn, it will listen to the specified socket address. After the TCP client calls socket() and connect() in turn, it wants the TCP server to send a connection request. After the TCP server listens for this request, it will call the accept() function to receive the request, so the connection is established. After that, you can start network I/O operations, that is, read and write I/O operations similar to ordinary files.
Int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
The first parameter of the accept function is the socket description word of the server, the second parameter is a pointer to the struct sockaddr *, which is used to return the protocol address of the client, and the third parameter is the length of the protocol address. If accpet succeeds, then the return value is a new descriptive word automatically generated by the kernel that represents the TCP connection to the returning client.
Note: The first parameter of accept is the socket description word of the server, which is generated by the server starting to call the socket() function, which is called the listening socket description word; and the accept function returns the connected socket description word. A server usually only creates one listen socket descriptor, which persists throughout the life of the server. The kernel creates a connected socket descriptor for each client connection accepted by the server process. When the server completes a service to a client, the corresponding connected socket descriptor is closed.
3.5, read (), write () and other functions
Everything is only owing to the wind, so the server and the customer have established a connection. You can call the network I / O to read and write operations, that is, to achieve communication between different processes in the network! Network I/O operations have the following groups:
· read()/write()
· recv()/send()
· readv()/writev()
· recvmsg()/sendmsg()
· recvfrom()/sendto()
I recommend using the recvmsg()/sendmsg() function, which is the most common I/O function. You can actually replace the other functions above with these two functions. Their declarations are as follows:
#include
Ssize_t read(int fd, void *buf, size_t count);
Ssize_t write(int fd, const void *buf, size_t count);
#include
#include
Ssize_t send(int sockfd, const void *buf, size_t len, int flags);
Ssize_t recv(int sockfd, void *buf, size_t len, int flags);
Ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
Const struct sockaddr *dest_addr, socklen_t addrlen);
Ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
Struct sockaddr *src_addr, socklen_t *addrlen);
Ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
Ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
The read function is responsible for reading the contents from fd. When the read is successful, read returns the actual number of bytes read. If the returned value is 0, the end of the file has been read, and less than 0 indicates that an error has occurred. If the error is EINTR, the read is caused by the interrupt, and if it is ECONNREST, the network connection is out of order.
The write function writes the contents of the nbytes byte in the buf to the file descriptor fd. The number of bytes written back is successful. Returns -1 on failure and sets the errno variable. In a web application, there are two possibilities when we write to a socket file descriptor. 1) The return value of write is greater than 0, indicating that some or all of the data is written. 2) The returned value is less than 0 and an error has occurred. We have to deal with it according to the type of error. If the error is EINTR, an interrupt error occurs during writing. If there is a problem with the IPIPE for the network connection (the other party has closed the connection).
I will not introduce these pairs of I/O functions one by one. For details, see the man document or baidu, Google. The following examples will use send/recv.
3.6, close () function
After the server establishes a connection with the client, some read and write operations are performed. When the read and write operations are completed, the corresponding socket description word is closed. For example, the open file is called to close the open file.
#include
When closing the default behavior of a TCP socket, the socket is marked as closed, and then immediately returned to the calling process. The descriptor can no longer be used by the calling process, which means it can no longer be the first parameter of read or write.
Note: The close operation simply causes the reference count of the corresponding socket descriptor to be -1. Only when the reference count is 0, the TCP client is triggered to send a termination request to the server.
4, TCP three-way handshake in the socket to establish a connection
We know that tcp establishes a connection to perform a "three-way handshake", that is, to exchange three packets. The general process is as follows:
· The client sends a SYN J to the server
· The server responds to the client with a SYN K and acknowledges SYN J with ACK J+1
· The client then wants the server to send a confirmation ACK K+1
Figure 1. TCP three-way handshake sent in the socket
As can be seen from the figure, when the client calls connect, it triggers the connection request and sends the SYN J packet to the server. At this time, the connect enters the blocking state; when the server listens for the connection request, it receives the SYN J packet and calls the accept function. Receiving a request to send SYN K, ACK J+1 to the client, then accept enters the blocking state; after the client receives the server's SYN K, ACK J+1, then connect returns and confirms the SYN K; the server receives When ACK K+1 is reached, accept returns. At this point, the three-way handshake is completed and the connection is established.
Summary: The client's connect returns the second time in the three-way handshake, while the server-side accept returns the third time in the three-way handshake.
5, TCP four-way handshake release connection in the socket
The three-way handshake establishment process of TCP in socket is introduced above, and the socket function involved. Now let's introduce the process of releasing the connection by the four-way handshake in the socket. Please see the following figure:
Figure 2. TCP four-way handshake sent in the socket
The illustration process is as follows:
An application process first calls close to actively close the connection, at which time TCP sends a FIN M;
After receiving the FIN M, the other end performs a passive shutdown to confirm the FIN. Its reception is also passed to the application process as a file terminator, because the reception of FIN means that the application process can no longer receive additional data on the corresponding connection;
After a while, the application process that receives the end-of-file call closes its socket. This causes its TCP to also send a FIN N;
The source sender TCP receiving this FIN acknowledges it.
This has a FIN and ACK in each direction.
6, an example (practice)
Having said that, I will practice it. Write a simple server, client (using TCP) - the server always listens to the port 6666 of the machine, if it receives the connection request, it will receive the request and receive the message sent by the client; the client and the server establish Connect and send a message.
Server-side code:
Service-Terminal
#include
Client code:
Client
#include
Of course, the above code is very simple, there are a lot of shortcomings, this is just a simple demonstration of the basic functions of the socket. In fact, no matter how complicated the network program is, these basic functions are used. The above server uses the iterative mode, that is, only after processing a client request to process the next client's request, such server processing capability is very weak, and the actual server needs to have concurrent processing capability! In order to require concurrent processing, the server needs fork() a new process or thread to process the request.
We are supplier of Disposable Vapes 3000 puffs also distributor a lot of brand. We offer full range of 3000+ Puffs Disposable Vapes, You'll find all Disposable Vape on tsvaping.com.
Disposable Vape 3000 Puffs FOLI BAR Factory Wholesale ;
We offer full range of 3000+ Puffs Disposable Vapes.tsvaping has served thousands of vape wholesalers from worldwide since 2018. Is your e-cigarette wholesale good partner.
The FOLI BAR 3000 Puffs Disposable Vape Wholesale Pen Device is a great way to enjoy your favorite nicotin salt e-liquids.
Wholesale vape 3000 puffs rechargeable disposable Vape Pen . Short Description: Model Number, air glow fun. Brand Name, FOLI. Origin from China.
Vape 3000 Puffs,Hqd Vape Flavors,Hyde Vape Puffs,Flash Vape Pen
TSVAPE Wholesale/OEM/ODM , https://www.tsecigarette.com