zoukankan      html  css  js  c++  java
  • 多路复用的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 . ");
     76         while(1){
     77 
     78 //              printf("-------------1----------- ");          
     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("------------------------ ");
    86                 if(0 > ret){
     87                         perror("select");
     88                         return -1;
     89                 }else if(0 == ret){  //////如果超时运行这个条件
     90                         printf("Timeout. ");
     91                         continue;
     92                 }else{
     93                         /////select成功
     94 //              printf("-------------1----------- ");          
     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-----------


    ");              
    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    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. "    , i);
    128                                                 continue;
    129                                         }
    130                                         printf("SOCKET[%d]: %s[%d]


    ", i, bu    f, num);
    131                                 } //if
    132                         } //for
    133                 } //if
    134         } //while
    135 }

  • 相关阅读:
    进程
    并发编程
    操作系统的发展史
    __init__、__new__、__call__ 方法
    MongoDB文档操作
    MongoDB集合操作
    MongoDB数据库操作
    MongoDB连接
    MongoDB的文档存储结构
    MongoDB 概念
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3228762.html
Copyright © 2011-2022 走看看