📄 p12-15.c
字号:
#include <sys/types.h>#include <sys/socket.h>#include <sys/time.h>#include <netinet/in.h>#include <netdb.h>#include <stdio.h>#define MAXBUFSIZE 1024int socket_listen(const char *, const char *);int main(int argc, char **argv){ int i,maxi,maxfd,listenfd,connfd,sockfd; int nready,client[FD_SETSIZE]; ssize_t n; fd_set rset,allset; char buf[MAXBUFSIZE]; size_t clilen; struct sockaddr_in servaddr,cliaddr; int rval; struct timeval to; /* 创建服务套接字并建立侦听队列 */ listenfd = socket_listen(NULL, "2003"); /* 初始化描述字集合、最大描述字个数、客户数组client以及其索引maxi、 */ FD_ZERO(&allset); FD_SET(listenfd, &allset); maxfd = listenfd; for (i=0; i<FD_SETSIZE; i++) client[i] = -1; /* -1表示该登记项没有记录 */ maxi = -1; /* 等待客户 */ while (1) { rset = allset; /* 等待到达新的连接或者新的输入*/ printf("server waiting\n"); nready = select(maxfd + 1, &rset, NULL, NULL, NULL); /* 判别就绪的是连接还是输入 */ if (FD_ISSET(listenfd, &rset)){ /*如果就绪的是listenfd,意味到达了新的连接 */ /* 接收连接 */ clilen = sizeof(cliaddr); connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen); /* 加入这个新客户至客户数组 */ for (i = 0; i<FD_SETSIZE; i++) if (client[i] < 0){ client[i] = connfd; break; } if (i == FD_SETSIZE) { printf("too many clients\n"); exit(1); } /* 加入这个新连接的套接字至描述字集合 */ FD_SET(connfd,&allset); printf("adding client on fd %d\n",connfd); if (connfd > maxfd) maxfd = connfd; /* 记录最大连接数,用于select */ if(i > maxi) maxi = i; /* 记录当前最大客户数 */ if (--nready <= 0) /* 若无可读的套接字,回去等待下一个就绪套接字 */ continue; } /* 就绪集合中有可读套接字,逐一处理其中的每一个 */ for (i = 0; i <= maxi; i++) { if ((sockfd = client[i]) < 0) /* 无效记录 */ continue; if (FD_ISSET(sockfd, &rset)){ /* 如果是读就绪套接字 */ /* 读该套接字。若遇到文件尾,关闭它并从就绪集合中清除 */ if ((n = read(sockfd, buf, MAXBUFSIZE)) == 0){ close(sockfd); FD_CLR(sockfd,&allset); client[i] = -1; } else { /* 否则,处理请求并回答客户 */ sleep(5); printf("serving client on fd %d\n",sockfd); write(sockfd, buf, n); } if (--nready <= 0) /* 已无可读套接字 */ break; } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -