千家信息网

Linux 高级I/O之poll函数及简单服务器客户端编程

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,当需要同时监听多个文件描述符时,就需要I/O复用函数,I/O复用函数有select、poll、epoll,今天主要使用poll函数。poll()接受一个指向结构'struct pollfd'列表的指针
千家信息网最后更新 2026年10月31日Linux 高级I/O之poll函数及简单服务器客户端编程

当需要同时监听多个文件描述符时,就需要I/O复用函数,I/O复用函数有select、poll、epoll,今天主要使用poll函数。

poll()接受一个指向结构'struct pollfd'列表的指针,其中包括了你想测试的文件描述符和事件。事件由一个在结构中事件域的比特掩码确定。当前的结构在调用后将被填写并在事件发生后返回。

函数原型:

#includeint poll(struct pollfd *fds, nfds_t nfds, int timeout);struct pollfd{    int fd;         /*file descriptor*/    short events;   /*requested events*/    short revents;  /*returned events*/}

函数参数:fds是要监听的fd的数组,nfds是数组个数,timeout 超时时间 -1是阻塞;

函数说用:通过传入的events的类型去判断返回的类型是否一致,如果一致就该干事了。

events:


常量

说明

POLLIN

普通或优先级带数据可读

POLLRDNORM

普通数据可读

POLLRDBAND

优先级带数据可读

POLLPRI

高优先级数据可读

POLLOUT

普通数据可写

POLLWRNORM

普通数据可写

POLLWRBAND

优先级带数据可写

POLLERR

发生错误

POLLHUP

发生挂起

POLLNVAL

描述字不是一个打开的文件


接下来是是一个服务器监听两个socket的例子:

服务器代码:

#include#include  #include  #include  #include  #include  #include #include#include#include#define MAX_POLLFD_NUM 2//#define SERVER_CONN_IP1 "1.1.1.1"//#define SERVER_CONN_IP2 "1.1.1.1"#define DEFAULT_PORT 8000#define BUFF_MAX 1024typedef void(*Server_Rrocess_Thread_Fun)(void *arg);/*thread process function define */typedef struct sever_thread_fun{        Server_Rrocess_Thread_Fun Server_Process_Client_Conn1;        Server_Rrocess_Thread_Fun Server_Process_Client_Conn2;}Poll_Server_Process_Clinet_FUN_t;/*connect 1 thread function*/void *Poll_Conn1_Process(void *arg){        unsigned char ucBufArr[BUFF_MAX] = {0};        unsigned long ulSize = 0;        int connect_fd ;    printf("come pthread conn1 fun to proess conn1\n");        if( (connect_fd = accept( *(int*)arg, (struct sockaddr*)NULL, NULL)) == -1){                  printf("accept socket error: %s(errno: %d)",strerror(errno),errno);      }        ulSize = recv(connect_fd, ucBufArr, BUFF_MAX, 0);          if(send(connect_fd, "Hello,you are connected 1!\n", 26,0) == -1)          perror("send error");          ucBufArr[ulSize] = '\0';      //sleep(20);        printf("recv msg from client: %s\n", ucBufArr);          close(connect_fd);          pthread_exit((void*)1);}/*connect 1 thread function*/void *Poll_Conn2_Process(void *arg){        unsigned char ucBufArr[BUFF_MAX] = {0};        unsigned long ulSize = 0;               int connect_fd ;    printf("come pthread conn2 fun to proess conn2\n");        if( (connect_fd = accept( *(int*)arg, (struct sockaddr*)NULL, NULL)) == -1){                  printf("accept socket error: %s(errno: %d)",strerror(errno),errno);      }        ulSize = recv(connect_fd, ucBufArr, BUFF_MAX, 0);          if(send(connect_fd, "Hello,you are connected 2!\n", 26,0) == -1)          perror("send error");          ucBufArr[ulSize] = '\0';     // sleep(20);        printf("recv msg from client: %s\n", ucBufArr);          close(connect_fd);          pthread_exit((void*)2);}int main(){           int poll_ret = 0;        pthread_t thread_conn1;        pthread_t thread_conn2;    /*socket var*/        int server_socket_fd_conn1;        int server_socket_fd_conn2;        struct sockaddr_in servaddr_conn1;        struct sockaddr_in serveraddr_conn2;        /*poll var*/    struct pollfd pollfd_arr[MAX_POLLFD_NUM];        /*init thread fun*/        Poll_Server_Process_Clinet_FUN_t server_conn_handel;        server_conn_handel.Server_Process_Client_Conn1 = Poll_Conn1_Process;        server_conn_handel.Server_Process_Client_Conn2 = Poll_Conn2_Process;        /*create two server socket*/        if( (server_socket_fd_conn1 = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){      printf("create socket conn1 error: %s(errno: %d)\n",strerror(errno),errno);      exit(0);      }          if( (server_socket_fd_conn2 = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){      printf("create socket conn2 error: %s(errno: %d)\n",strerror(errno),errno);      exit(0);      }              /*init socket 1 for conn1*/      memset(&servaddr_conn1, 0, sizeof(servaddr_conn1));      servaddr_conn1.sin_family = AF_INET;            servaddr_conn1.sin_addr.s_addr = htonl(INADDR_ANY);     servaddr_conn1.sin_port = htons(DEFAULT_PORT); //      if( inet_pton(AF_INET, SERVER_CONN_IP1, &servaddr_conn1.sin_addr.s_addr) <= 0){   //   printf("inet_pton error for %s\n",SERVER_CONN_IP1);    //  exit(0);     // }          /*init socket 2 for conn2*/          memset(&serveraddr_conn2, 0, sizeof(serveraddr_conn2));      serveraddr_conn2.sin_family = AF_INET;      serveraddr_conn2.sin_addr.s_addr = htonl(INADDR_ANY);     serveraddr_conn2.sin_port = htons(DEFAULT_PORT+1); //      if( inet_pton(AF_INET, SERVER_CONN_IP2, &serveraddr_conn2.sin_addr.s_addr) <= 0){   //   printf("inet_pton error for %s\n",SERVER_CONN_IP2);    //  exit(0);     // }        /*bind connect 1 socket*/    if( bind(server_socket_fd_conn1, (struct sockaddr*)&servaddr_conn1, sizeof(servaddr_conn1)) == -1){      printf("bind socket error1: %s(errno: %d)\n",strerror(errno),errno);      exit(0);      }          /*bind connect 2 socket*/        if( bind(server_socket_fd_conn2, (struct sockaddr*)&serveraddr_conn2, sizeof(serveraddr_conn2)) == -1){      printf("bind socket error2: %s(errno: %d)\n",strerror(errno),errno);      exit(0);      }      /*listen connect 1*/      if( listen(server_socket_fd_conn1, 10) == -1){      printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);      exit(0);      }          /*listen connect 2*/      if( listen(server_socket_fd_conn2, 10) == -1){      printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);      exit(0);      }          pollfd_arr[0].events = POLLRDNORM;/*only read event*/        pollfd_arr[0].fd = server_socket_fd_conn1;                pollfd_arr[1].events = POLLRDNORM;/*only read event*/        pollfd_arr[1].fd = server_socket_fd_conn2;    while(1)        {                poll_ret = poll( pollfd_arr, MAX_POLLFD_NUM,-1);                if( pollfd_arr[0].revents & POLLRDNORM )                {                        /*connect 1 process task*/                        pthread_create( &thread_conn1, NULL, server_conn_handel.Server_Process_Client_Conn1, (void *)(&pollfd_arr[0].fd));                }                if( pollfd_arr[1].revents & POLLRDNORM )                {                        /*connect 2 process task*/                        pthread_create( &thread_conn2, NULL, server_conn_handel.Server_Process_Client_Conn2, (void *)(&pollfd_arr[1].fd));                }                sleep(1);        }        return 0;}

客户端代码:

#include  #include  #include  #include  #include  #include  #include    #define BUFF_MAX 1024#define DEFAULT_PORT 8000int main(int argc, char** argv)  {      int    sockfd, n,rec_len;      char    recvline[BUFF_MAX], sendline[BUFF_MAX];      char    buf[BUFF_MAX];      struct sockaddr_in    servaddr;          if( argc != 2){      printf("usage: ./client \n");      exit(0);      }        /*create socket*/    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){      printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);      exit(0);      }              memset(&servaddr, 0, sizeof(servaddr));      servaddr.sin_family = AF_INET;      servaddr.sin_port = htons(DEFAULT_PORT/*+1/);/*DEFAULT_PORT is connect 1 to server,DEFAULT_PORT+1 is connect 2 to server*/          /*string ip to int ip*/    if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){      printf("inet_pton error for %s\n",argv[1]);      exit(0);      }      /*connect server*/    if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){      printf("connect error: %s(errno: %d)\n",strerror(errno),errno);      exit(0);      }              printf("send msg to server: \n");      fgets(sendline, BUFF_MAX, stdin);          /*write data to sockfd*/    if( send(sockfd, sendline, strlen(sendline), 0) < 0)      {      printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);      exit(0);      }          /*read socket data*/    if((rec_len = recv(sockfd, buf, BUFF_MAX,0)) == -1) {         perror("recv error");         exit(1);      }      buf[rec_len]  = '\0';      printf("Received : %s \n",buf);          /*colse socket*/    close(sockfd);      exit(0);  }

解释:服务器端监听 ip 127.0.0.1 port 8000和ip 127.0.0.1 port 8001

结果演示:


数据 函数 普通 事件 优先级 监听 服务器 服务 文件 结构 一致 代码 数组 类型 复用 客户 客户端 接下来 两个 个数 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 上海喔噻互联网科技有限公司 互联网科技网 西安纸贵互联网科技有限公司 互联网和科技技术 互联网金融监管科技数据 工业互联网科技新基建 上海互联网科技有限公司 互联网科技革命 长亮科技互联网金融 互联网科技公司介绍 科技大学互联网专业好不好 湖南洣水互联网科技有限公司扣款 互联网经济与金融科技 成都互联网科技公司工作好不好 互联网科技扶贫时间 乌鲁木齐新华智原互联网科技学校 四川慕妮娅互联网科技有限公司 上海创道互联网络科技有限公司 全球科技与互联网公司市值变化 江苏互联网智能科技产品出厂价 互联网的科技创新 壕鑫互联网络科技 伴你行互联网科技有限公司 互联网 新科技 互联网公司会议桌创意科技软装饰 互联网大会黑科技排名 互联网在线教育科技创业 银行科技岗属于互联网吗 吉林省码上互联网科技电话 瑞安市蟠桃会互联网科技有限公司
0