< 0) {// 找client[]中没有使用的位置client[i] = connfd;// 保存accept返回的文件描述符到client[]里 break;}if (i == FD_SETSIZE) {// 达到select能监控的文件个数上限 1024fputs("too many clients\n", stderr);exit(1);}FD_SET(connfd, &allset);// 向监控文件描述符集合allset添加新的文件描述符connfdif (connfd > maxfd)maxfd = connfd;// select第一个参数需要if (i > maxi) {maxi = i;// 保证maxi存的总是client[]最后一个元素下标 }if (--nready == 0) {continue;}}for (i = 0; i <= maxi; i++) {// 检测哪个clients 有数据就绪if ((sockfd = client[i]) < 0) {continue;}if (FD_ISSET(sockfd, &rset)) {if ((n = Read(sockfd, buf, sizeof(buf))) == 0) {// 当client关闭链接时,服务器端也关闭对应链接 */Close(sockfd);FD_CLR(sockfd, &allset);// 解除select对此文件描述符的监控client[i] = -1;} else if (n > 0) {for (j = 0; j < n; j++)buf[j] = toupper(buf[j]);Write(sockfd, buf, n);Write(STDOUT_FILENO, buf, n);}if (--nready == 0) {break;// 跳出for, 但还在while中}}}}Close(listenfd);return 0;}
wrap.h
#ifndef WRAP_H #define WRAP_H #include#include
wrap.c
#include "stdio.h"#include "unistd.h"#include "sys/types.h"#include "sys/stat.h"#include "fcntl.h"#include "stdlib.h"#include "string.h"#include "sys/socket.h"#include "ctype.h"#include "arpa/inet.h"#include "wrap.h" void perr_exit(const char *s) { perror(s); exit(1); } int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr) { int n; again: if((n = accept(fd, sa, salenptr)) < 0) { if((ECONNABORTED == errno) || (EINTR == errno)) goto again; else perr_exit("accept error"); } return n; } void Bind(int fd, const struct sockaddr *sa, socklen_t salen) { if(bind(fd, sa, salen) < 0) perr_exit("bind error"); } void Connect(int fd, const struct sockaddr *sa, socklen_t salen) { if(connect(fd, sa, salen) < 0) perr_exit("connect error"); } void Listen(int fd, int backlog) { if(listen(fd, backlog) < 0) perr_exit("listen error"); } int Socket(int family, int type, int protocol) { int n; if((n = socket(family, type, protocol)) < 0) perr_exit("socket error"); return n; } ssize_t Read(int fd, void *ptr, size_t nbytes) { ssize_t n; again: if((n = read(fd, ptr, nbytes)) == -1) { if(EINTR == errno) goto again; else return -1; }return n; } ssize_t Write(int fd, const void *ptr, size_t nbytes) { ssize_t n; again: if((n = write(fd, ptr, nbytes)) == -1) { if(EINTR == errno) goto again; else return -1; } return n; } void Close(int fd) { if(close(fd) == -1) perr_exit("close error");} ssize_t Readn(int fd, void *vptr, size_t nbytes) { size_t nleft; size_t nread; char *ptr; ptr = vptr; nleft = nbytes; while(nleft > 0) { if((nread = read(fd, ptr, nleft)) < 0) { if(EINTR == errno)nread = 0; else return -1; } else if(nread == 0) break; nleft -= nread; ptr += nread; } return (nbytes-nleft); } static ssize_t my_read(int fd,char *ptr){static int read_cnt;static char * read_ptr;static char read_buf[100];if(read_cnt <= 0){again:if((read_cnt == read(fd,read_buf,sizeof(read_buf))) < 0){if(errno == EINTR)goto again;return -1;}else if(read_cnt == 0)return 0;read_ptr = read_buf;}read_cnt--;*ptr = *read_ptr++;return 1;}ssize_t Readline(int fd,void *vptr,size_t maxlen){ssize_t n,rc;char c,*ptr;ptr = vptr;for(n = 1;n < maxlen;n ++){if((rc = my_read(fd,&c)) == 1){*ptr++ = c;if(c == '\n')break;}else if(rc == 0){*ptr = 0;return n - 1;}else{return -1;}}*ptr = 0;return n;}ssize_t Writen(int fd, const void *vptr, size_t nbytes) { size_t nleft; size_t nwritten; const char *ptr; ptr = vptr; nleft = nbytes; while(nleft > 0) { if((nwritten = write(fd, ptr, nleft))
- 【PET材料的生产设备】——导电滑环应用实例,厂家讲解
- 音视频入门基础——笔记
- linux下限制mongodb内存,MongoDB 4.2 限制内存
- IEEE VIS2022会议网站导读——Contribute
- 二、用户身份与文件权限
- 图论学习笔记——连通度
- 语音识别——MFCC理解
- 简单linux shell脚本监控磁盘使用情况,发送邮件告警
- Linux服务器查看负载情况
- 查看Linux服务器的负载情况