zoukankan      html  css  js  c++  java
  • linux select 网络模型

    io模型:

      同步IO: 阻塞形式,非阻塞形式(轮询)、信号驱动IO、IO复用(select, poll, epoll);

      异步io:aio_read()

    典型场景:

      1、客户端处理多种IO-------标准io 和网络io(套接字)

      2、server端既要处理监听套接字又要处理已连接的套接字

      3、一个服务器要处理TCP,又要处理UDP

      4、server端要处理多种服务多个协议;

      5、不管是网络套接字还是文件读写描述符均可处理;

      1 #include <stdio.h>
      2 #include <sys/select.h>
      3 #include <sys/time.h>
      4 #include <sys/types.h>
      5 #include <unistd.h>
      6 
      7 #include <netinet/in.h>
      8 #include <sys/socket.h>
      9 #include <string.h>         //bzero()
     10 
     11 int main()
     12 {
     13     int socketfd;
     14     struct sockaddr_in  serv_addr;    //struct socket address internet
     15     int i =0;
     16     /** /usr/include/netinet/in.h
     17      *  #define __SOCKADDR_COMMON(sa_prefix) 
     18      *    sa_family_t sa_prefix##family)
     19      *
     20      *  struct sockaddr_in{
     21      *      _SOCKADDR_COMMON(sin_); //展开宏sa_family_t  sin_family
     22      *      int_port_t sin_port;
     23      *      struct in_addr sin_addr;
     24      *  }
     25      *accept默认会阻塞进程,直到有一个客户连接建立后返回,
     26      *它返回的是一个新可用的套接字,这个套接字是连接套接字。
     27      *此时我们需要区分两种套接字,一种套接字正如accept的参数sockfd,它是监听套接字,
     28      *在调用listen函数之后,一个套接字会从主动连接的套接字变身为一个监听套接字;
     29      *而accept返回是一个连接套接字,它代表着一个网络已经存在的点点连接。
     30      *在调用listen函数之后,一个套接字会从主动连接的套接字变身为一个监听套接字;
     31      *而accept返回是一个连接套接字,它代表着一个网络已经存在的点点连接。
     32      *自然要问的是:为什么要有两种套接字?原因很简单,如果使用一个描述字的话,
     33      *那么它的功能太多,使得使用很不直观,同时在内核确实产生了一个这样的新的描述字.
     34      */
     35     //struct sockaddr_in serv_addr; 
     36     //address family, socket_stream, 0:会自动选择type类型对应的默认协议
     37     socketfd = socket(AF_INET,SOCK_STREAM, 0);
     38     if(socketfd){
     39 
     40     }
     41 
     42     bzero((char*)&serv_addr, sizeof(serv_addr));
     43     serv_addr.sin_family = AF_INET;         //主机字节序
     44     serv_addr.sin_port   = htons(7777);     //网络字节序
     45     serv_addr.sin_addr.s_addr =htonl(INADDR_ANY);   //监听所有地址 
     46 
     47     if(bind(socketfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))){
     48 
     49     }
     50 
     51     listen(socketfd, 100);
     52 
     53     int maxfd;
     54     fd_set allset, rset;
     55     maxfd = socketfd;
     56 
     57     FD_ZERO(&allset);           //将allset清零,使得集合中不含任何fd
     58     FD_SET(socketfd, &allset);  //将socketfd加入allset集合
     59 
     60     int sockfd, clilen, bytes;
     61     struct sockaddr_in cli_addr;
     62     char buffer[256];
     63 
     64     while(1){
     65         rset = allset;
     66        /*select第一个参数表示要检查的文件描述符的个数;比如最大值为5,因为
     67        *文件描述符是从0开始的,所以需要检查0,1,2,3,4,5这六个值;即最大值+1;
     68        */
     69         if(select(maxfd+1, &rset, NULL, NULL, NULL)){
     70 
     71         }
     72 
     73         for(i=0; i<=maxfd; i++){
     74             if(FD_ISSET(i, &rset)){     //一个个来判断是否被置位了
     75                 if(socketfd == i){      //监听套接字
     76                     clilen = sizeof(cli_addr);
     77                     sockfd = accept(socketfd, (struct sockaddr*)&cli_addr, (socklen_t*)&clilen);
     78                     if(sockfd<0){   //error
     79                         perror("accept error 
    ");
     80                     }
     81                     FD_CLR(i, &rset);   //清零
     82                     maxfd = maxfd>sockfd?maxfd:sockfd;
     83                     FD_SET(sockfd, &allset);
     84 
     85                 }else{                  //通信套接字
     86                     bzero(buffer, 256);
     87                     bytes = recv(i, buffer, 256, 0);
     88                     if(bytes <= 0){     //client端退出
     89                         FD_CLR(i, &allset); //清零
     90                         close(i);
     91                         continue;
     92                     }
     93                     printf("recv msg: %s", buffer);
     94                     send(i, buffer, 255, 0);
     95                 }
     96             }
     97         }
     98     }
     99 
    100     return 0;
    101 }
  • 相关阅读:
    操作excel文件的基础工具xlrd/xlwt/xlutils学用
    第12课 OpenGL 显示列表
    第11课 OpenGL 飘动的旗帜
    第10课 OpenGL 3D世界
    第09课 OpenGL 移动图像
    第08课 OpenGL 混合
    第07课 OpenGL 光照和键盘(2)
    第07课 OpenGL 光照和键盘(1)
    第06课 OpenGL 纹理映射
    第05课 OpenGL 3D空间
  • 原文地址:https://www.cnblogs.com/chris-cp/p/4948396.html
Copyright © 2011-2022 走看看