对于poll的总结

     参考书籍:linux高性能服务器编程,是个人对看书的总结,上文一致

    poll系统调用和select类似,(个人认为poll和select掌握一个就好了)也是在指定时间内轮询一定数量的文件描述符,以测试其中是否有就绪者。

    关于poll的原型

     #include <poll.h>

     int poll(struct pollfd* fds,nfds_t nfds,int timeout);

     (1)fds参数是一个pollfd结构类型的数组,它指定我们所有的感兴趣的文件描述符上发生的可读可写和异常等事件。pollfd结构体的定义如下:

      struct pollfd

      {

            int fd;//文件描述符

            short events;//注册的事件,在这里声明我们要关心的事件是什么

            short revents;//实际发生的事件,由内核填充,这个我们是不用去管的

       }

       poll有许多的事件类型,我目前接触或者说用到的是

       POLLIN,数据可读(包括普通数据和优先数据)

       POLLRDHUP,TCP连接被对方关闭,或者对方关闭了写操作,他由GUN引入

       POLLHUP,挂起,比如管道的写端被关闭后,读端描述符上将收到POLLHUP事件。

       通常,应用程序需要recv调用的返回值来区分socket上面接收到的是有效数据还是对方关闭连接的请求,并做相应的处理。但是poll可以通过POLLRDHUP事件来进行判断。

        (2)对于nfds,他制定的是被监听事件集合fds的大小。

        (3)对于timeout他的单位是毫秒制定的是poll的超时值,当timeout是-1,poll调用将一直阻塞,直到某个事件发生;当timeout为0,那么poll调用将立即返回。

        poll返回值的含义和selec相同,,如果超时且没有任何描述符就绪,那么返回0,如果失败则返回-1,如果成功那么就返回就绪文件描述符的总数,如果在等待期间接收到了信

号那就返回-1。


用poll监听其他进程发来信息的代码

#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <poll.h>


int main()
{
   int sockfd = socket(AF_INET,SOCK_STREAM,0);
   assert(sockfd!=-1);


   struct sockaddr_in saddr,caddr;


   saddr.sin_family = AF_INET;
   saddr.sin_port = htons(6500);
   saddr.sin_addr.s_addr = inet_addr("192.168.1.11");


   int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
   assert(res!=-1);


   int ret = listen(sockfd,5);
   assert(ret!=-1);


   int len = sizeof(caddr);
   int c = accept(sockfd,(struct sockaddr*)&caddr,&len);




    struct pollfd rdset;//read
    //init
    rdset.fd = c;//choose
    rdset.events = POLLIN;
    rdset.revents = 0;


    while(1)
    {
         int n = poll(&rdset,1,0);
         if(n<0)
         {
              break;
         }


         if(n>0)
         {
             char buff[128] = {0};
             int ret = recv(c,buff,127,0);
             if(ret<=0)
             {
                  printf("over!");
                  break;
             }
             printf("%s",buff);
         }
    }
    return 0;
}

         

相应的客户端代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


int main(int argc,char *argv[])
{
   int sockfd = socket(AF_INET,SOCK_STREAM,0);
   assert(sockfd!=-1);


   struct sockaddr_in saddr;//虽然操作一样,但是客户端是为了去链接服务端
   memset(&saddr,0,sizeof(saddr));
   saddr.sin_family = AF_INET;
   saddr.sin_port = htons(6500);//转换成大端
   saddr.sin_addr.s_addr = inet_addr("192.168.1.11");
 //要用就必须先运行起来
   int res = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));//链接到服务端上面
   assert(res!=-1);
   //执行到这个地方说明三次握手完成


   while(1)
   {
       printf("input:\n");
       char buff[128] = {0};


       fgets(buff,128,stdin);//fgets会用到空格回车
       if(strncmp(buff,"end",3)==0)
       {
           break;
       }


       send(sockfd,buff,strlen(buff),0);//把收到的讯息再发送出去
       memset(buff,0,128);
   }


   close(sockfd);//关闭
   return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: epoll、select和poll是用于实现I/O多路复用的机制,它们之间有以下区别: 1. 存储方式:select和poll采用轮询的方式来检查文件描述符是否处于就绪态,而epoll采用回调机制。这意味着随着文件描述符数量的增加,select和poll的效率会线性降低,而epoll不会受到太大影响,除非活跃的socket很多。\[1\] 2. 返回就绪文件描述符:select和poll并不会明确指出是哪些文件描述符就绪,而epoll会返回就绪的文件描述符。这使得在调用select和poll后,程序需要遍历监听的整个文件描述符来找到哪些处于就绪态,而epoll则可以直接处理就绪的文件描述符。\[1\] 3. 效率:由于epoll使用回调机制和红黑树的数据结构,它的效率比select和poll更高。而select和poll需要将有关文件描述符的数据结构拷贝进内核,最后再拷贝出来,而epoll创建的有关文件描述符的数据结构本身就存于内核态中,利用mmap()文件映射内存加速与内核空间的消息传递,减少了复制开销。\[1\]\[2\] 4. 边缘触发模式:epoll支持边缘触发模式,这意味着只有在文件描述符状态发生变化时才会通知应用程序,而不是在文件描述符处于就绪态时一直通知。这可以提高效率,避免充斥大量不关心的就绪文件描述符。\[1\] 总结来说,epoll相对于select和poll具有更高的效率和更好的扩展性,特别适用于大规模并发的网络编程。而select和poll则适用于较小规模的并发处理。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *2* *3* [epollpoll、select的原理和区别](https://blog.csdn.net/wwwvipp/article/details/119888373)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值