select
- Select the number of file descriptors can monitor is limited FD_SETSIZE, generally 1024, simply change the number of open file descriptors process does not change the number of select monitor file
- 1024 solved using select the following client is very appropriate, but if too many links to the client, select uses a polling model, will greatly reduce the efficiency of server response should not be to invest more in select fine
#include <SYS / SELECT .h> / * ACCORDING to Earlier Standards * / #include <SYS / time.h> #include <SYS / types.h> #include <unistd.h> int SELECT ( int NFDs, the fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval * timeout); NFDs: file descriptor set monitor's maximum file descriptor plus one, because this parameter tells the kernel state how many file descriptors before detection readfds: monitor there are a set of file descriptors to read data arrives, inbound and outbound parameters writefds: monitoring data arrives write file descriptor collection, inbound and outbound parameters exceptfds: monitoring abnormal collection of file descriptors, such as abnormal band data arrives, pass outgoing parameters timeout: Timing blocking monitoring time, three cases 1.NULL, wait forever 2 provided timeval, waiting for a fixed time. 3 disposed in timeval times are 0, returns immediately check descriptor after polling. Struct timeval { Long the tv_sec; / * seconds The * / Long tv_usec; / * microseconds * / }; void FD_CLR macros ( int fd, the fd_set * sET ); // the file descriptor fd cleared the collection 0 int FD_ISSET ( int fd, the fd_set * sET ); // test whether the file descriptor fd is set in the collection. 1 void the FD_SET ( int FD, the fd_set * SET ); // the file descriptor fd in the set position 1 void FD_ZERO (* fd_set the SET ); // the file descriptor in the set all bits to 0
server
/* server.c */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <netinet/in.h> #include <arpa/inet.h> #include "wrap.h" #define MAXLINE 80 #define SERV_PORT 6666 int main(int argc, char *argv[]) { int i, maxi, maxfd, listenfd, connfd, sockfd; int nready, client[FD_SETSIZE]; /* FD_SETSIZE 默认为 1024 */ ssize_t n; fd_set rset, allset; char buf[MAXLINE]; char str[INET_ADDRSTRLEN]; /* #define INET_ADDRSTRLEN 16 */ socklen_t cliaddr_len; struct sockaddr_in cliaddr, servaddr; listenfd = Socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); Bind(listenfd, (struct sockaddr *)&servaddr, the sizeof (servaddr)); the Listen (listenfd, 20 is ); / * default maximum 128 * / maxFd = listenfd; / * Initialization * / Maxi = - . 1 ; / * Client [] subscript * / for (I = 0 ; I <FD_SETSIZE; I ++ ) Client [I] = - . 1 ; / * -1 for initialization Client [] * / FD_ZERO ( & allset); the FD_SET (listenfd, & allset); / * configured to monitor file descriptor select set * / for (;;) { RSET = allset; / * all new set select the monitor signal sets each cycle * / nready = select (maxFd + . 1 , & RSET, NULL, NULL, NULL); IF (nready < 0 ) perr_exit ( " select error " ); IF (FD_ISSET (listenfd, & RSET)) { / * new new Client Connection * / cliaddr_len = the sizeof (cliaddr); connfd = the Accept (listenfd, ( struct the sockaddr *) & cliaddr, & cliaddr_len); the printf ( "% S from AT PORT Received% D \ n- " , inet_ntop (AF_INET, & cliaddr.sin_addr, STR, the sizeof (STR)), ntohs (cliaddr.sin_port)); for (I = 0 ; I <FD_SETSIZE; I ++ ) { IF (Client [I] < 0 ) { Client [I] = connfd; / * save file descriptor returned to accept Client [] in * / BREAK ; } } / * reached the maximum number of files to monitor select 1024 * / IF (I == FD_SETSIZE) { fputs ( " TOO MANY Clients \ n-" , Stderr); Exit ( . 1 ); } the FD_SET (connfd, & allset); / * add a new file descriptor to the monitor signal in the set * / IF (connfd> maxFd) maxFd = connfd; / * SELECT first parameters needed * / IF (I> Maxi) Maxi = I; / * update Client [] max index value * / IF (--nready == 0 ) Continue ; / * If no more file descriptors continue into the ready to select the top blocking monitor, Ready handles and the unprocessed file descriptor * / } For (I = 0 ; I <= Maxi; I ++) { / * which clients detect data ready * / IF ((sockfd = Client [I]) < 0 ) Continue ; IF (FD_ISSET (sockfd, & RSET)) { iF ((n-= the Read (sockfd, buf, MAXLINE)) == 0 ) { the Close (sockfd); / * when the client closes the link server also closes the corresponding link * / FD_CLR macros (sockfd, & allset); / * releasing select monitor this file descriptor * / Client [I] = - . 1 ; } else { int j; for (j = 0; j < n; j++) buf[j] = toupper(buf[j]); Write(sockfd, buf, n); } if (--nready == 0) break; } } } close(listenfd); return 0; }
client
/* client.c */ #include <stdio.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #include "wrap.h" #define MAXLINE 80 #define SERV_PORT 6666 int main(int argc, char *argv[]) { struct sockaddr_in servaddr; char buf[MAXLINE]; int sockfd, n; sockfd = Socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr); servaddr.sin_port = htons(SERV_PORT); Connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); while (fgets(buf, MAXLINE, stdin) != NULL) { Write(sockfd, buf, strlen(buf)); n = Read(sockfd, buf, MAXLINE); if (n == 0) printf("the other side has been closed.\n"); else Write(STDOUT_FILENO, buf, n); } Close(sockfd); return 0; }
Contains "wrap.c" and "wrap.h" file on two blog, not repeat it here gives