多路复用的server模型

多路复用的server模型多路复用I/O之server模型 主要是关于select()这个函数:其原型是:intselect(intn,fd_set*read_fds,fd_set*write_fds,fd_set *except,structtimeval*timeout);功能是:监测指定集合中指定文件描述符的指定事件是否发生;参数一:读集合,监测登记文件描述的读事件;

多路复用的server模型多路复用I/O之server模型

 主要是关于select()这个函数:

其原型是:int select(int n,fd_set *read_fds,fd_set *write_fds,fd_set 

*except,struct timeval *timeout);

功能是:监测指定集合中指定文件描述符的指定事件是否发生;

参数一:读集合,监测登记文件描述的读事件;

参数二:写集合,监测登记文件描述的写事件

参数三:报错集合,监测登记文件描述的报错事件

void FD_CLR(int fd, fd_set *set);
//从指定集合中把指定文件描述删



int  FD_ISSET(int fd, fd_set *set);
//测试指定集合中的指定文件描述

的事件

void FD_SET(int fd, fd_set *set);
//向指定集合中添加指定文件描述

void FD_ZERO(fd_set *set);
//初始化集合

  1 #include <stdio.h>

  2 #include <sys/time.h>

  3 #include <sys/types.h>

  4 #include <unistd.h>

  5 #include <fcntl.h>

  6 #include <sys/types.h>          /* See NOTES */

  7 #include <sys/socket.h>

  8 #include <netinet/in.h>

  9 #include <arpa/inet.h>

 10 

 11 #include <string.h>

 12 

 13 #define PORT    6543

 14 

 15 int main()

 16 {

 17         /*创建套接字,用于连接*/

 18         int s = socket(AF_INET, SOCK_STREAM, 0);

 19         if(0 > s){

 20                 perror(“socket”);

 21                 return -1;

 22         }

 23 

25 

 26         /*端口重用*/

 27         int reuseaddr = 1;

 28         if(0 > setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, 

sizeof(re    useaddr))){

 29                 perror(“setsockopt”);

 30                 return -1;

 31         }

 32 

 33 

 34 

 35         /*绑定server IP及端口号*/

 36         struct sockaddr_in addr;

 37         memset(&addr, 0, sizeof(struct sockaddr_in));

 38         addr.sin_family = AF_INET;

 39         addr.sin_port = htons(PORT);

 40         addr.sin_addr.s_addr = htonl(INADDR_ANY);

 41 

 42         socklen_t addrlen = sizeof(struct sockaddr_in);

 43         /*struct sockaddr_in addr初始化必须,socklen_t addrlen*/

 44         if(0 > bind(s, (struct sockaddr *)&addr, addrlen)){

 45                 perror(“bind”);

 46                 return -1;

 47         }

 48 

 49         /*设置监听数*/

 50         listen(s, 10);

 51 

 52         /*设置套接字为非阻塞*/

 53         int val = fcntl(s, F_GETFL, 0);

 54         val |= O_NONBLOCK;

 55         fcntl(s, F_SETFL, val);

 56 

 57         /*初始化读集合*/

 58         fd_set oldset, newset;

 59 /这里将oldset集合初始化

 60         FD_ZERO(&oldset);

 61 

 62 将开始的套接字添加到集合oldset中

 63         FD_SET(s, &oldset);

 64 

 65 

 66 ///这里用maxfd得到最大的套接字数

 67         int maxfd = s+1;

 68 

 69 //这里设置为select功能实现的时间,超过跳过

 70         struct timeval tm = {

 71                 .tv_sec = 1,

 72                 .tv_usec= 0,

 73         };

 74 

 75         printf(“Wait for connecting .\n”);

 76         while(1){

 77 

 78 //              printf(“————-1———–\n”);          

 79 将oldset这个集合copy给newset(动态包含的套接字的集合)

 80                 newset = oldset;

 81                 //int ret = select(maxfd, &newset, NULL, NULL, 

&tm);

 82 

 83 下面将集合newset,用读监听,而且这里没有设置功能运行时间

 84                 int ret = select(maxfd, &newset, NULL, NULL, NULL);

 85                 printf(“————————\n”);

86                 if(0 > ret){

 87                         perror(“select”);

 88                         return -1;

 89                 }else if(0 == ret){  //如果超时运行这个条件

 90                         printf(“Timeout.\n”);

 91                         continue;

 92                 }else{

 93                         /select成功

 94 //              printf(“————-1———–\n”);          

 95                         /*测试用于连接的套接字,看是否有新连接进来

*/

 96                         if(FD_ISSET(s, &newset)){

 97                                 struct sockaddr_in newaddr;

 98                                 memset(&newaddr, 0, sizeof(struct 

sockaddr_i    n));

 99                                 socklen_t newlen = sizeof(struct 

sockaddr_in    );

100                                 /*有新连接进来,得到用于读写到套接

字*/

101                                 int news = accept(s, (struct 

sockaddr *)&new    addr, &newlen);

102                                 if(0 > news){

103                                         perror(“accept”);

104                                         return -1;

105                                 }

106                                 /*把套接字保存进集合*/

107                         //      printf(“————-1———–

\n”);              

108 

109                                 FD_SET(news, &oldset);

110                                 if(news+1 > maxfd) {

111                                         maxfd = news+1;

112                                 }

113                 //              maxfd++;

114                                 printf(“New connect: SOCKET[%d], %

s:%d\n”, n    ews, inet_ntoa(newaddr.sin_addr), ntohs

(newaddr.sin_port));

115                         }

116 

117                         for(int i = s+1; i < maxfd; i++){

118                                 /*测试用于读写到套接字,看哪个客户

端发数据进

    来*/

119                                 if(FD_ISSET(i, &newset)){

120                                 #define MAX 64

121                                         char buf[MAX];

122                                         bzero(buf, MAX);

123                                         int num = recv(i, buf, MAX, 

0);

124                                         if(0 >= num){

125                                                 FD_CLR(i, &oldset);

126                                                 close(i);

127                                                 printf(“SOCKET[%d] 

leave.\n”    , i);

128                                                 continue;

129                                         }

130                                         printf(“SOCKET[%d]: %s[%d]

\n”, i, bu    f, num);

131                                 } //if

132                         } //for

133                 } //if

134         } //while

135 }今天的文章多路复用的server模型分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/30513.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注