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 }  
    运行结果:
     
  • 相关阅读:
    python远程连接服务器并查看服务器上的文件
    python中xe6x80xa5xe8xafx8a如何转为中文
    idea+testng+maven环境搭建
    Django restfulframework系列
    django-基于函数的视图与基于类的视图
    yaml结合数据驱动编写测试用例
    pycharm社区版找不到工具栏找不到Database的解决办法
    Content-Type 对照表
    ffmpeg C# 切第一秒的有图片
    Angular HttpClient POST 服务器(springboot)获取不到参数问题
  • 原文地址:https://www.cnblogs.com/jiangzhaowei/p/8831079.html
Copyright © 2011-2022 走看看