select poll epoll实例

select 

main() 
{ 
    int sock; 
    FILE *fp; 
    struct fd_set fds; 
    struct timeval timeout={3,0}; //select等待3秒,3秒轮询,要非阻塞就置0
    char buffer[256]={0}; //256字节的接收缓冲区
    /* 假定已经建立UDP连接,具体过程不写,简单,当然TCP也同理,主机ip和port都已经给定,要写的文件已经打开
    sock=socket(...); 
    bind(...); 
    fp=fopen(...); */ 
    while(1) 
   { 
        FD_ZERO(&fds); //每次循环都要清空集合,否则不能检测描述符变化
        FD_SET(sock,&fds); //添加描述符
        FD_SET(fp,&fds); //同上
        maxfdp=sock>fp?sock+1:fp+1;    //描述符最大值加1
        switch(select(maxfdp,&fds,&fds,NULL,&timeout))   //select使用
        { 
            case -1: exit(-1);break; //select错误,退出程序
            case 0:break; //再次轮询
            default: 
                  if(FD_ISSET(sock,&fds)) //测试sock是否可读,即是否网络上有数据
                  { 
                        recvfrom(sock,buffer,256,.....);//接受网络数据
                        if(FD_ISSET(fp,&fds)) //测试文件是否可写
                            fwrite(fp,buffer...);//写入文件
                         buffer清空;
                   }// end if break; 
          }// end switch 
     }//end while 
}//end main 

 poll

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <sys/select.h>
#include <poll.h>
#include <netdb.h>
#include <limits.h>
 
 
#define ip "192.168.188.133"
#define port 8888
#define INFTIM 10000
 
int main(int argc, char* argv[])
{
  int afd, sfd;
  struct sockaddr_in servaddr;
 
  //创建socket文件描述符
  sfd = socket(AF_INET, SOCK_STREAM, 0);
  if(sfd == -1)
  {
    perror("sfd == -1");
    exit(1);
  }
 
  //防止端口复用
  int reuse = 1 ;
  setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*)&reuse, sizeof(reuse));
 
  //初始化socket
  
  memset(&servaddr, 0, sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons(port) ;
  servaddr.sin_addr.s_addr = inet_addr(ip);
 
  //绑定套接字
  if(bind(sfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1)
  {
    perror("bind error");
    exit(1);
  }
 
  //监听套接字
  if(listen(sfd, 5) == -1)
  {
    perror("listen error");
    exit(1);
  }
 
  struct pollfd fdarr[4];
 
  fdarr[0].fd = sfd;
  fdarr[0].events = POLLIN;
 
  for(int i = 1; i < 4; ++i)
  {
    fdarr[i].fd = -1;
  }
  int maxfd = sfd;
  int confd;
  int i = 1;
  while(1)
  {
    int flag = poll(fdarr, maxfd + 1, INFTIM);
 
    if(flag == -1)
    {
      perror("poll error");
      exit(1);
    }
 
    if(fdarr[0].revents & POLLIN)//监听套接字可读
    {
      confd = accept(sfd, NULL, NULL);
 
      for(i = 1; i < 4; ++i)
      {
        if(fdarr[i].fd == -1)
        {
          fdarr[i].fd = confd;
          fdarr[i].events = POLLIN;
          break;
        }
      }
 
      if(i == 4)
      {
        perror("too many client");
        exit(1);
      }
      if(fdarr[i].fd > maxfd)
      {
        maxfd = fdarr[i].fd;
      }
    }
 
    for(i = 1; i < 4; ++i)
    {
      if(fdarr[i].fd == -1)
      {
        continue;
      }
      if(fdarr[i].revents & (POLLIN | POLLERR))
      {
        int readn;
        char buf[10];
        memset(buf, 0, 10);
        if((readn = read(fdarr[i].fd, buf, 10)) < 0)
        {
          if(errno == ECONNRESET)
          {
            close(fdarr[i].fd);
            fdarr[i].fd = -1;
 
          }else
          {
            perror("read error");
          }
        }else if(readn == 0)
        {
          close(fdarr[i].fd);
          fdarr[i].fd = -1;
        }else
        {
          printf("%s\n", buf);
        }
 
      }
    }

  }
 
  //关闭套接字
  close(sfd);
 
  return 0;
}

 

posted @ 2021-05-08 11:42  摸鱼选手LLF  阅读(87)  评论(0编辑  收藏  举报