Network programming-socket communication process

Communication process

The TCP/socket communication process is divided into client and server, which are introduced separately below

Service-Terminal

The server side is the role of passively accepting connections, the main steps are as follows

  1. Create a socket for monitoring socket()
    -Monitor: monitor connections with clients
    -Socket: equivalent to a file descriptor, the socket is only used for monitoring
  2. Bind the listening file descriptor with the local IP and port (IP and port are the address information of the server) bind() The
    client connects to the server using this IP and port
  3. Set up the listener, and the listener fd starts to work listen()
  4. Blocking and waiting, when a client initiates a connection, unblocks, accepts the client's connection, and gets the socket for communication with the client (fd) accept()
    Every time a client communicates, a new socket is created
  5. Communication
    Receive/send data recv() send()
  6. The communication is over, disconnect the connection close()

Client

The client usually initiates a connection actively, there are the following steps

  1. Create a socket for communication (fd)
  2. Connect to the server, specify the IP and port of the connected server
  3. Connection is successful, communication
  4. End of communication, disconnect

Communication process diagram

The above communication steps can be represented by a process diagram: the
Insert picture description here
establishment of a connection refers to the three-way handshake process, see TCP protocol detailed explanation for details

Socket function

This part introduces the specific definition of each function in the figure above. All functions can be viewed through the man manual.
Header files to include:

#include <sys/types.h>
#include <sys/socket.h>

Or just use a header file

#include <arpa/inet.h>

Create socket()

The philosophy of Linux is that everything is a file. Socket is no exception, it is a file descriptor that is readable and writable, controllable and close.

int socket(int domain, int type, int protocol);

Function: Create a socket
Parameters:

  • domain: protocol family

    • AF_INET: ipv4
    • AF_INET6: ipv6
    • AF_UNIX, AF_LOCAL: local socket communication
  • type: the type of protocol used in the communication process

    • SOCK_STREAM: Streaming protocol
    • SOCK_DGRAM: report protocol
  • protocol: A specific protocol. Generally write 0

    • SOCK_STREAM: The streaming protocol uses TCP by default
    • SOCK_DGRAM: The report protocol uses UDP by default

return value:

  • Success: The file descriptor is returned, and the kernel buffer is manipulated.
  • Failed: -1

Bind/name bind()

The address family is specified when the socket is created, but the specific socket address that uses the address family is not specified
. Binding a socket to the socket address is called naming the socket. In the server program, the socket is usually named because the client only knows how to connect to it after naming it. The client does not need to name the socket, but uses the socket address automatically assigned by the operating system in an anonymous way.

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); // socket命名

bind assigns the socket address pointed to by addr to the unnamed sockfd file descriptor, and the addrlen parameter indicates the length of the socket address

  • Function: bind, bind fd and local IP + port
  • parameter:
    • sockfd: the file descriptor obtained through the socket function
    • addr: the socket address to be bound, this address encapsulates the information of the ip and port number
    • addrlen: the memory size occupied by the second parameter structure

Listen()

int listen(int sockfd, int backlog); // /proc/sys/net/core/somaxconn
  • Function: monitor the connection on this socket
  • parameter:
    • sockfd: the file descriptor obtained through the socket() function
    • backlog: the maximum number of unconnected and connected sockets

Accept connection accept()

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
  • Function: Receive client connection, the default is a blocking function, blocking waiting for client connection
  • parameter:
    • sockfd: file descriptor for monitoring
    • addr: outgoing parameter, which records the client's address information (ip, port) after a successful connection
    • addrlen: specify the corresponding memory size of the second parameter
  • return value:
    • Success: File descriptor used for communication
    • -1: failed

Initiate a connection connect()

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • Function: Client connects to server
  • parameter:
    • sockfd: file descriptor used for communication
    • addr: the address information of the server that the client wants to connect to
    • addrlen: the memory size of the second parameter
  • Return value: success 0, failure -1

Close the connection close()

Closing the connection is actually closing the
header file required by the socket corresponding to the connection :

#include <unistd.h>

int close(int fd);

fd is the socket to be closed. The
close system call does not close immediately, but decrements the reference count of fd by one. Really close when the count is 0

In a multi-process program, a fork system call by default will increase the reference count of the socket opened in the parent process by 1, so the close call must be performed on the socket in both the parent process and the child process to close the connection

Guess you like

Origin blog.csdn.net/MinutkiBegut/article/details/114268072