免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1776 | 回复: 1
打印 上一主题 下一主题

使用 epoll 问题。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-06-11 00:17 |只看该作者 |倒序浏览
  1. #include <pthread.h>

  2. #include <sys/epoll.h>

  3. #include <sys/types.h>
  4. #include <sys/socket.h>
  5. #include <arpa/inet.h>
  6. #include <netdb.h>
  7. #include <unistd.h>
  8. #include <fcntl.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <errno.h>

  13. #define maxevents 200
  14. #define max_thread 6000
  15. #define MAXLINE   1024
  16. #define max_connect 5

  17. void *work(void *arg);
  18. void setnonblocking(int sock);
  19. void do_use_fd(struct epoll_event   *events);

  20. pthread_mutex_t lock_mutex = PTHREAD_MUTEX_INITIALIZER;

  21. int lines   = 0;
  22. int epollfd = 0;

  23. int main(){

  24.         pthread_t pid_t;
  25.         struct epoll_event ev, events[maxevents]={0};

  26.         int nfds   = 0;        
  27.         int n      = 0;
  28.         int status = 0;

  29.         //lock_mutex = PTHREAD_MUTEX_INITIALIZER;


  30.         status = pthread_create(&pid_t, NULL, work, NULL);  // 起一个线称建立连接

  31.         if (0 == status) {               
  32.                 printf(" pthread created \n");
  33.         } else {
  34.                 perror(" pthread create fail\n");
  35.                 return 0;
  36.         }


  37.         epollfd  = epoll_create(maxevents);                   // 建立epoll

  38.         if (-1 == epollfd){           
  39.                 perror("error cannot epoll_create\n");
  40.                 return 0;
  41.         } else {
  42.                 printf("epollfd = %d  \n", epollfd);
  43.         }

  44.         printf(" begin epoll_wait \n");

  45.         for (;;) {

  46.                 //printf("befor epoll_wait %d \n", &(events[0]));   
  47.                 nfds = epoll_wait(epollfd, events, maxevents, 500); // 开始抓回复
  48.                 printf(" after  epoll_wait nfds = %d\n", nfds);

  49.                 if(nfds == -1){
  50.                         perror("nfds == -1 ");
  51.                         return 0;
  52.                 }else {
  53.                         printf("nfds = %d \n", nfds);
  54.                 }

  55.                 for(n = 0; n < nfds; ++n) {                       
  56.                         do_use_fd(&(events[n]));
  57.                 } // end for         
  58.         } // end for        
  59.         return 0;
  60. }



  61. void *work(void *arg){  // 这个就是工作线称主要发起连接

  62.         int i = 0 ;
  63.         int create_conn = 1;
  64.         struct sockaddr_in clientadd;
  65.         int client;
  66.         struct epoll_event ev;
  67.         int len = 0;

  68.         pthread_detach(pthread_self());  // this


  69.         for (;;){

  70.                 create_conn = 1;
  71.                 pthread_mutex_lock(&lock_mutex);

  72.                 if (lines > max_connect){
  73.                         create_conn = 0;                   
  74.                 }
  75.                 pthread_mutex_unlock(&lock_mutex);

  76.                 if (0 == create_conn){
  77.                         sleep(1);
  78.                         continue;       
  79.                 }

  80.                 // else
  81.                 client = socket(AF_INET , SOCK_STREAM, 0);
  82.                 if (client < 0){
  83.                         sleep(1);                  
  84.                         continue;        
  85.                 }

  86.                 printf("begin memset \n");
  87.                 memset(&clientadd, 0, sizeof(clientadd));

  88.                 clientadd.sin_family = AF_INET;
  89.                 clientadd.sin_addr.s_addr  =  inet_addr("192.168.1.150");  
  90.                 clientadd.sin_port  = htons(80);
  91.                 setnonblocking(client);

  92.                 ev.events  =  EPOLLOUT;
  93.                 ev.data.fd =  client;

  94.                 if (epoll_ctl(epollfd, EPOLL_CTL_ADD, client, &ev) < 0) {
  95.                         printf(" fd = %d ", client);
  96.                         perror("epoll set insertion error");                       
  97.                         return NULL;

  98.                 } else {               
  99.                         printf(" add to %d epoll pool\n", epollfd);
  100.                 }

  101.                 printf("begin connect \n");

  102.                 connect(client, (struct sockaddr*)&clientadd, sizeof(clientadd));
  103.                 printf("begin connect \n");

  104.                 pthread_mutex_lock(&lock_mutex);
  105.                 ++lines;           
  106.                 printf(" now lines = %d \n", lines);
  107.                 pthread_mutex_unlock(&lock_mutex);

  108.         } // end for
  109. }

  110. void setnonblocking(int sock){
  111.         int opts;
  112.         opts=fcntl(sock,F_GETFL);
  113.         if(opts<0)
  114.         {
  115.                 perror("fcntl(sock,GETFL)");
  116.                 exit(1);
  117.         }

  118.         opts = opts|O_NONBLOCK;
  119.         if(fcntl(sock,F_SETFL,opts)<0)
  120.         {
  121.                 perror("fcntl(sock,SETFL,opts)");
  122.                 exit(1);
  123.         }
  124. }

  125. void do_use_fd(struct epoll_event   *events){


  126.         struct epoll_event ev;
  127.         int n  =  0;

  128.         char buff[100] ="get / http/1.1\r\n\r\n";
  129.         char inbuff[MAXLINE] ={0};
  130.         int client = events->data.fd;
  131.         int closeit = 1;

  132.         printf(" in do user fd \n");

  133.         if (events->events & EPOLLIN){ // 可以读了

  134.                 if ( (client = events->data.fd) < 0) return;

  135.                 while (1) {
  136.                         if ( (n = read(client, inbuff, MAXLINE)) < 0) {

  137.                                 if (errno == ECONNRESET) {

  138.                                         printf("readline error  errno == ECONNRESET\n");                                       
  139.                                         break;

  140.                                 } else {

  141.                                         printf("readline error no data \n");               
  142.                                         closeit = 0;
  143.                                         break;
  144.                                 }

  145.                         } else if (n == 0) {
  146.                                 printf("readline == 0 \n");
  147.                                 break;
  148.                         } else {
  149.                                 printf("i get %d byte form %d \n", n ,client);
  150.                         }
  151.                 } // end while (1)

  152.                 if (1 == closeit) {
  153.             printf("close socket %d now \n", client);
  154.                         close(client);
  155.                         ev.events = EPOLLIN |EPOLLERR;
  156.                     ev.data.fd = client;
  157.                     epoll_ctl(epollfd, EPOLL_CTL_DEL, client, &ev);  
  158.        
  159.                         pthread_mutex_lock(&lock_mutex);
  160.                         --lines;           
  161.                         printf(" now lines = %d \n", lines);
  162.                         pthread_mutex_unlock(&lock_mutex);
  163.                         return;
  164.                 }
  165.         }  else if (events->events & EPOLLOUT) // end if

  166.          {
  167.                 if ( (client = events->data.fd) < 0) return;
  168.                 printf(" now write %d \n",events->data.fd);
  169.                 n = write(events->data.fd, buff, strlen(buff));

  170.                 printf("%d  write = %d \n", lines, n);
  171.                 ev.events = EPOLLIN |EPOLLERR;
  172.                 ev.data.fd = client;
  173.                 epoll_ctl(epollfd, EPOLL_CTL_MOD, client, &ev);               
  174.                 return;        
  175.         }

  176.         //close(events->data.fd); //读完了 就短掉连接

  177. }
复制代码


本意是一个网络爬虫,不断去不同的服务器获取网页。 采用epoll 而不是多线称+简单的代码。

因为是爬虫 所以需要不断的发起连接。 这个连接可以在 epoll_wait 里面建立也可以起一个线程,在线程里面建立
我采用了后者。

目前的问题是,  只能运行一次。 当一条连结,建立,完成后,断开。 再次建立第二个连接 当使用的是上次被关闭的那个fd
程序就死了
help

论坛徽章:
0
2 [报告]
发表于 2007-06-12 11:37 |只看该作者
你需要把你的原有的event从epoll里边删除.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP