zoukankan      html  css  js  c++  java
  • Linux网络编程——tcp并发服务器(poll实现)

    想详细彻底地了解poll或看懂下面的代码请参考《Linux网络编程——I/O复用之poll函数》

    代码:

      1 #include <string.h>  
      2 #include <stdio.h>  
      3 #include <stdlib.h>  
      4 #include <unistd.h>  
      5 #include <sys/select.h>  
      6 #include <sys/time.h>  
      7 #include <sys/socket.h>  
      8 #include <netinet/in.h>  
      9 #include <arpa/inet.h>  
     10 #include <poll.h>  
     11 #include <errno.h>  
     12 #define OPEN_MAX 100  
     13   
     14 int main(int argc, char *argv[])  
     15 {  
     16     //1.创建tcp监听套接字  
     17     int sockfd = socket(AF_INET, SOCK_STREAM, 0);  
     18       
     19     //2.绑定sockfd  
     20     struct sockaddr_in my_addr;  
     21     bzero(&my_addr, sizeof(my_addr));  
     22     my_addr.sin_family = AF_INET;  
     23     my_addr.sin_port = htons(8000);  
     24     my_addr.sin_addr.s_addr = htonl(INADDR_ANY);  
     25     bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr));  
     26       
     27     //3.监听listen  
     28     listen(sockfd, 10);  
     29       
     30     //4.poll相应参数准备  
     31     struct pollfd client[OPEN_MAX];  
     32     int i = 0, maxi = 0;  
     33     for(;i<OPEN_MAX; i++)  
     34         client[i].fd = -1;//初始化poll结构中的文件描述符fd  
     35       
     36     client[0].fd = sockfd;//需要监测的描述符  
     37     client[0].events = POLLIN;//普通或优先级带数据可读  
     38       
     39     //5.对已连接的客户端的数据处理  
     40     while(1)  
     41     {  
     42         int ret = poll(client, maxi+1, -1);//对加入poll结构体数组所有元素进行监测  
     43           
     44         //5.1监测sockfd(监听套接字)是否存在连接  
     45         if((client[0].revents & POLLIN) == POLLIN )  
     46         {  
     47             struct sockaddr_in cli_addr;  
     48             int clilen = sizeof(cli_addr);  
     49             int connfd = 0;  
     50             //5.1.1 从tcp完成连接中提取客户端  
     51             connfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);  
     52               
     53             //5.1.2 将提取到的connfd放入poll结构体数组中,以便于poll函数监测  
     54             for(i=1; i<OPEN_MAX; i++)  
     55             {  
     56                 if(client[i].fd < 0)  
     57                 {  
     58                     client[i].fd = connfd;  
     59                     client[i].events = POLLIN;  
     60                     break;  
     61                 }  
     62             }  
     63               
     64             //5.1.3 maxi更新  
     65             if(i > maxi)  
     66                 maxi = i;  
     67                   
     68             //5.1.4 如果没有就绪的描述符,就继续poll监测,否则继续向下看  
     69             if(--ret <= 0)  
     70                 continue;  
     71         }  
     72           
     73         //5.2继续响应就绪的描述符  
     74         for(i=1; i<=maxi; i++)  
     75         {  
     76             if(client[i].fd < 0)  
     77                 continue;  
     78               
     79             if(client[i].revents & (POLLIN | POLLERR))  
     80             {  
     81                 int len = 0;  
     82                 char buf[128] = "";  
     83                   
     84                 //5.2.1接受客户端数据  
     85                 if((len = recv(client[i].fd, buf, sizeof(buf), 0)) < 0)  
     86                 {  
     87                     if(errno == ECONNRESET)//tcp连接超时、RST  
     88                     {  
     89                         close(client[i].fd);  
     90                         client[i].fd = -1;  
     91                     }  
     92                     else  
     93                         perror("read error:");  
     94                       
     95                 }  
     96                 else if(len == 0)//客户端关闭连接  
     97                 {  
     98                     close(client[i].fd);  
     99                     client[i].fd = -1;  
    100                 }  
    101                 else//正常接收到服务器的数据  
    102                     send(client[i].fd, buf, len, 0);  
    103                   
    104                 //5.2.2所有的就绪描述符处理完了,就退出当前的for循环,继续poll监测  
    105                 if(--ret <= 0)  
    106                     break;  
    107                   
    108             }  
    109         }  
    110     }  
    111     return 0;  
    112 }  
    运行结果:
     
  • 相关阅读:
    Pascal's Triangle II
    Pascal's Triangle
    Best Time to Buy and Sell Stock II
    Best Time to Buy and Sell Stock
    Populating Next Right Pointers in Each Node
    path sum II
    Path Sum
    [转载]小波时频图
    [转载]小波时频图
    [转载]Hilbert变换及谱分析
  • 原文地址:https://www.cnblogs.com/jiangzhaowei/p/8831079.html
Copyright © 2011-2022 走看看