How to connect multiple clients to the server in linux socket

11-03-2023

I. Introduction

In practice, people often encounter situations where multiple clients are connected to the server. Because the functions introduced before, such as connect,recv,send, etc., are all blocking functions, if the resources are not fully prepared, the process calling this function will go to sleep, so that I/O multiplexing cannot be handled.

This paper gives two methods of I/O multiplexing: fcntl () and select (). It can be seen that socket is regarded as a special file descriptor in Linux, which brings great convenience to users.

Second, fcntl

The fcntl () function has the following characteristics:

1) non-blocking I/O: cmd can be set to F_SETFL and lock to O_NONBLOCK.

2) Signal-driven I/O: You can set cmd to F_SETFL and lock to O_ASYNC.

Routine:

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SERVPORT 3333# define BACKLOG 10#define MAX_CONNECTED_NO 10#define MAXDATASIZE 100int main(){ struct sockaddr_in server_sockaddr,client_sockaddr; int sin_size,recvbytes,flags; int sockfd,client_fd; char buf[MAXDATASIZE]; /* create socket */if ((sockfd = socket (af _ inet, sock _ stream, 0)) = =-1) {perror ("socket"); exit(1); } printf("socket success! ,sockfd=%d ",sockfd); /* set the sockaddr structure */server _ sockaddr.sin _ family = af _ inet; server_sockaddr.sin_port=htons(SERVPORT); server_sockaddr.sin_addr.s_addr=INADDR_ANY; bzero(&(server_sockaddr.sin_zero),8); /* bind the local ip address to the port number */if (bind (sockfd, (struct sockaddr *) & server _ sockaddr, sizeof (struct sockaddr)) =-1) {perror ("bind"); exit(1); } printf("bind success! "); /* monitoring */if (listen (sockfd, backlog) = =-1) {perror ("listen"); exit(1); } printf("listening .... "); /*fcntl () function, handling multiplexed I/O */if ((flags = fcntl (sockfd, f _ setfl, 0)) to run the program:

[root@localhost net]# ./fcntlsocket success! ,sockfd=3bind success! listening....accept: Resource temporarily unavailable

As you can see, when the resources of accept are unavailable, the program will automatically return.

If you replace the red bold code with:

If ((flags = fcntl (sockfd, f _ setfl, 0)) runs as follows:

[root@localhost net]# ./fcntl1socket success! ,sockfd = 3bind success! listening ...

It can be seen that the process has been waiting until another related signal drives it.

Third, select

#include #include #include #include #include #include #include #include #include #include #include #include #define SERVPORT 3333#define BACKLOG 10# define MAX_CONNECTED_NO 10#define MAXDATASIZE 100int main(){ struct sockaddr_in server_sockaddr,client_sockaddr; int sin_size,recvbytes; fd_set readfd; fd_set writefd; int sockfd,client_fd; char buf[MAXDATASIZE]; /* create socket */if ((sockfd = socket (af _ inet, sock _ stream, 0)) = =-1) {perror ("socket"); exit(1); } printf("socket success! ,sockfd=%d ",sockfd); /* set the sockaddr structure */server _ sockaddr.sin _ family = af _ inet; server_sockaddr.sin_port=htons(SERVPORT); server_sockaddr.sin_addr.s_addr=INADDR_ANY; bzero(&(server_sockaddr.sin_zero),8); /* bind the local ip address to the port number */if (bind (sockfd, (struct sockaddr *) & server _ sockaddr, sizeof (struct sockaddr)) =-1) {perror ("bind"); exit(1); } printf("bind success! "); /* monitoring */if (listen (sockfd, backlog) = =-1) {perror ("listen"); exit(1); } printf("listening .... "); /*select*/ FD_ZERO(&readfd); //Empty the readfd to FD_SET(sockfd,&readfd); //Add sockfd to the readfd set while (1) {sin _ size = sizeof (struct sockaddr _ in); If (select (max _ connected _ no, & readfd, null, null, (struct timeout (FD _ isset (sockfd, & readfd) > 0) {//FD _ isset this macro determines whether sockfd belongs to a readable file descriptor. Read in from sockfd and output to standard output. If ((client _ FD = accept (SOCKFD, (struct SOCKADR *) & client _ SOCKADR,&sin _ size)) =-1) {//client _ SOCKADR: client address perror("accept "); exit(1); } if((recvbytes=recv(client_fd,buf,MAXDATASIZE,0))==-1){ perror("recv"); exit(1); } if(read(client_fd,buf,MAXDATASIZE)

Copyright Description:No reproduction without permission。

Knowledge sharing community for developers。

Let more developers benefit from it。

Help developers share knowledge through the Internet。

Follow us