tcp multi-client connection in network communication

  There are too many tcp instances in network programming, and I have written them several times (ashamed). Today I am thinking about how to write one-to-one TCP, but what about one-to-many? How does the server know to send data to that? Students who are doing development should often hear about the attribute uid. So why do you know by the UID that the data to be sent is for the correct user?

  When not very busy. Take a closer look at several APIs of TCP and their parameters. Let's take a look at these APIs and parameters:

  1. Description: When a socket socket is created, the socket is not connected with information such as the local address and port, and the bind function will complete these tasks

 

Included header files
<sys/types.h>
<sys/socket.h>
原型:
int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);
return value:
    0: success
    1: Failed

returned error code

 

EACCES: The address is protected and the user is not a superuser.
EADDRINUSE: The specified address is already in use.
EBADF: The sockfd parameter is an invalid file descriptor.
EINVAL: The socket has been bound to the address.
ENOTSOCK: The parameter sockfd is the file descriptor

  1. Description: The listen function uses the active connection socket to become the connected socket, so a process can accept other requests, making it a server process. In short, the LISTEN function in the TCP server turns the process into a server process, from active to passive
include header files
#include<sys/socket.h>
prototype:
int listen(int sockfd, int backlog)
return value:
    0: success
    1: Failed

Parameter parsing:

Parameter 1: socket

  The socket used by the listen function, sockfd was previously returned by the socket function. When the socket fd returned by the socket function is an actively connected socket, that is, the system assumes that the user will call the connect function on this socket, expecting it to actively connect with other processes, and then In server programming, users hope that this socket can accept incoming connection requests, that is, passively waiting for users to connect. Since the system considers a socket to be actively connected by default, it needs to tell the system in some way that the user process completes this through the system call listen.

Parameter 2: backlog:

  This parameter involves some network details. While the process is handling connection requests one by one, there may be other connection requests. Because a TCP connection is a process, there may be a semi-connected state, and sometimes due to too many users trying to connect at the same time, the server process cannot complete the connection request quickly. If this happens, what does the server process want the kernel to do? The kernel will maintain a queue in its own process space to track these completed connections but the server process has not yet taken over processing or ongoing connections. Such a queue cannot be made arbitrarily large by the kernel, so there must be an upper limit on the size. This backlog tells the kernel to use this value as the upper bound. Undoubtedly, the server process can not specify a value arbitrarily, the kernel has a permitted range. This range is implementation-dependent. It is difficult to have some kind of unification, generally this value will be less than 30.

  1. Description: accept(). Accept the connection from the client and establish a socket corresponding to the client.

  Note: On the server side, the socket returned by socket() is used to listen and accept client connection requests. This socket cannot be used to send and receive data to and from clients. accept() accepts a client's connection request and returns a new socket. The so-called "new" means that this socket is not the same socket as the socket returned by socket() for listening and accepting client connection requests. Communication with this accepting client is done by sending and receiving data on this new socket.

  

head File:
#include <sys/types.h>
#include <sys/socket.h>
prototype:
int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen)
return value:
    >0: success
    <0: Fail and return error code

Parameter explanation:

  socketfd: The socket descriptor established by the system call socket() is bound to a local address (usually the server's socket) through bind(), and the connection has been monitored through listen();

  addr: A pointer to struct sockaddr, which is filled with the address of the peer socket of the communication layer server (usually the client address), and the exact format of the return address addr is determined by the address type of the socket (such as TCP or UDP) ;If addr is NULL and there is no valid address to fill in, in this case, addrlen is not used and should be set to NULL;

  addrlen: a value result parameter, the calling function must be initialized to a value containing the size of the structure pointed to by addr, and the function returns the actual value of the peer address (usually the server address);

  • Let's take a look at the general process of the server:
1:    server_sock = socket();
2:    bind(server_sock);
3:    listen(server_sock);
4:    client_sock = accept(server_sock);
5:    close(server_sock);
6:    send(client_sock, data);
7:    recv(client_sock, data);
8:    close(client_sock);

Did you find that the fourth point created a new socket ! The sockets for sending and receiving data are newly created after accpet. Yes, the server sends data to the correct client through this socket. You might say that the common ones are all sent via UID. That's right! That's because the developer has done a layer of encapsulation and stored the socket as a Value and the user's uid as a key in a corresponding relationship called hashmap, so that you can send data to the user through the UID as you know.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324734198&siteId=291194637