rawsocket

Tracker的socket部分都是封装在一个rawserver类中,一切的网络调用都不通过socket包,直接调用封装类。这个类就在bittorrent/rawserver.py中。

采用poll实现的非阻塞的socket,下面是pollfd:
   struct pollfd {
         int fd;        /* 文件描述符 */
         short events;  /* 等待的事件 */
         short revents; /* 实际发生了的事件 */
     };


下面是一个unix c的例子,摘自UNIX Programming FAQ 中文版 v0.1.0
  /* 检测两个文件描述符,分别为一般数据和高优先数据。如果事件发生
      则用相关描述符和优先度调用函数handler(),无时间限制等待,直到
      错误发生或描述符挂起。*/
   
   #include <stdlib.h>
   #include <stdio.h>
  
   #include <sys/types.h>
   #include <stropts.h>
   #include <poll.h>
  
   #include <unistd.h>
   #include <errno.h>
   #include <string.h>
  
   #define NORMAL_DATA 1
   #define HIPRI_DATA 2
  
   int poll_two_normal(int fd1,int fd2)
   {
       struct pollfd poll_list[2];
       int retval;
  
       poll_list[0].fd = fd1;
       poll_list[1].fd = fd2;
       poll_list[0].events = POLLIN|POLLPRI;
       poll_list[1].events = POLLIN|POLLPRI;
  
       while(1)
       {
           retval = poll(poll_list,(unsigned long)2,-1);
           /* retval 总是大于0或为-1,因为我们在阻塞中工作 */
  
           if(retval < 0)
           {
               fprintf(stderr,"poll错误: %s\n",strerror(errno));
               return -1;
           }
    
           if(((poll_list[0].revents&POLLHUP) == POLLHUP) ||
              ((poll_list[0].revents&POLLERR) == POLLERR) ||
              ((poll_list[0].revents&POLLNVAL) == POLLNVAL) ||
              ((poll_list[1].revents&POLLHUP) == POLLHUP) ||
              ((poll_list[1].revents&POLLERR) == POLLERR) ||
              ((poll_list[1].revents&POLLNVAL) == POLLNVAL))
             return 0;
  
           if((poll_list[0].revents&POLLIN) == POLLIN)
             handle(poll_list[0].fd,NORMAL_DATA);
           if((poll_list[0].revents&POLLPRI) == POLLPRI)
             handle(poll_list[0].fd,HIPRI_DATA);
           if((poll_list[1].revents&POLLIN) == POLLIN)
             handle(poll_list[1].fd,NORMAL_DATA);
           if((poll_list[1].revents&POLLPRI) == POLLPRI)
             handle(poll_list[1].fd,HIPRI_DATA);
       }
   }


具体的代码在listen_forever中出现,主体是一个无限循环,只有doneflag可以终止,根据任务的队列去poll各个period,每个period就是self.funcs[0][0] - bttime(),得到的结果就是event,然后把各个event给handle_event去处理。

handle的函数主要有三个方面,处理连接,读和写。

你可能感兴趣的:(C++,c,unix,socket,C#)