多路复用poll和域套接字

阅读: 评论:0

多路复用poll和域套接字

多路复用poll和域套接字

多路复用poll

#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
参数fds:要监控文件描述符集合struct pollfd {int   fd;         /* file descriptor */short events;     /* requested events */short revents;    /* returned events */};events和revents:POLLIN 有数据可读POLLOUT写数据POLLER指定文件描述符发生错误POLLRDHUP判断tcp的socket关闭了连接加上一个宏 _GNU_SOURCE #define _GNU_SOURCE 1#include <poll.h>nfds:监控多少个文件描述符timeout:超时(毫秒)> 0等待的时间==0非阻塞< 0阻塞 INFTIM返回值:成功,返回结构体revents域不为0的文件描述符个数失败,-1如果超时返回0
  1 /*================================================================2  *   Copyright (C) 2020 hqyj Ltd. All rights reserved.3  *   4  *   文件名称:02_多路复用01.c5  *   创 建 者:Chens6  *   创建日期:2020年04月24日7  *   描    述:执行的时候需要加sudo8  *9  ================================================================*/10  11  12 #include <stdio.h>13 #include <sys/time.h>14 #include <sys/types.h>15 #include <unistd.h>16 #include <sys/types.h>17 #include <sys/stat.h>18 #include <fcntl.h>19 #include <stdlib.h>20 #include <poll.h>21  22 int main(int argc, char *argv[])23 {24     //打开鼠标驱动文件25     int fd =-1;26     fd = open("/dev/input/mouse0",O_RDONLY);27     if(fd < 0){28         perror("open");29         exit(1);30     }31  32     //1,创建文件描述符集合33     struct pollfd fds[2];34     //2,把关心的文件描述符填入35     fds[0].fd = 0;//监控键盘36     fds[0].events = POLLIN;//监控键盘的输入37  38     fds[1].fd = fd;//监控鼠标39     fds[1].events = POLLIN;//监控鼠标输入40  41  42     int val =-1;43  44     while(1){45  46         val = poll(fds,2,1000);47         if(val <0){48             perror("poll");49             exit(1);50         }51         else if(0 == val){52             puts("-------超时了");53             continue;54         }55         else{56             if(fds[0].revents == POLLIN){57                 puts("键盘输入++++++++");58             }59             if(fds[1].revents == POLLIN){60                 puts("****鼠标动了***");61             }62         }63     }64     close(fd);65     return 0;66 }                                                                   

2、域套接字

​ 用于本地间通讯,域套接字 易用性、效率还可以不错

#include <sys/socket.h>
#include <sys/un.h>unix_socket = socket(AF_UNIX, type, 0);socket(AF_LOCAL,SOCK_STREAM,0);
socket(AF_LOCAL,SOCK_DGRAM ,0);struct sockaddr_un {sa_family_t sun_family;    填写AF_UNIXchar        sun_path[108]; 套接字文件绝对路径这个套接字必须事先不存在
};填充结构体struct sockaddr_un myaddr;bzero(&myaddr.sizeof(myaddr));myaddr.sun_family = AF_UNIX;strcpy(myaddr.sun_path,"/tmp/mysocket");

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LIUgZ7MG-1587912699172)(.1.png)]

#include <unistd.h>
int access(const char *pathname, int mode);
参数:pathname路径文件名mode:F_OK判断存在X_OK判断权限执行权限W_OK判断权限写权限R_OK判断权限读权限返回值:成功0失败-1
#include <unistd.h>
int unlink(const char *pathname);
返回值,成功0,失败-1
  1 /*================================================================2  *   Copyright (C) 2020 hqyj Ltd. All rights reserved.3  *               4  *   文件名称:01_域套接字服务器.c5  *   创 建 者:Chens6  *   创建日期:2020年04月26日7  *   描    述:  8  *               9  ================================================================*/10                  11                  12 #include <stdio.h>13 #include <stdint.h>14 #include <sys/types.h>15 #include <sys/socket.h>16 #include <stdlib.h>17 #include <unistd.h>18 #include <arpa/inet.h>19 #include <string.h>20 #include <errno.h>21 #include <sys/socket.h>22 #include <sys/types.h>23 #include <sys/wait.h>24 #include <sys/un.h>25                  26 #define  QUIT         "quit"27 #define BACKLOG       1028 #define PATH          "/tmp/20021/unix_sock"29                  30                  31 int main(int argc, char *argv[])32 {                33     int sockfd = -1;34     sockfd = socket(AF_LOCAL,SOCK_STREAM,0);35                  36     int b_reuse = 1;37     setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&b_reuse,sizeof(int));38                  39     struct sockaddr_un sun;40     bzero(&sun,sizeof(sun));41     sun.sun_family    = AF_LOCAL;42     strncpy(sun.sun_path,PATH,strlen(PATH));43                  44     if(!access(PATH,F_OK))unlink(PATH);45                  46     if(bind(sockfd,(struct sockaddr*)&sun,sizeof(sun))<0){47         perror("bind");48         exit(1); 49     }            50                  51     if(listen(sockfd,BACKLOG)<0){52         perror("listen");53         exit(1); 54     }            55                  56                  57     char buf[BUFSIZ]={};58                  59     //创建集合   60     fd_set readfds,temp;61     //初始化集合(清空集合)62     FD_ZERO(&readfds);63     FD_ZERO(&temp);64     //把关心的文件描述符加入集合65     FD_SET(0,&readfds);66     FD_SET(sockfd,&readfds);67                  68     puts("IO多路复用服务器就绪");69     int maxfd = sockfd;70     int val = -1;                                                            71     int i = -1;  72     ssize_t recv_t = -1;73                  74     int setfd = -1;75     int input_t = -1;76     int ret = -1;77     int acceptfd = -1;78     puts("输入方式:“客户端对应的文件描述符 内容");79     while(1){    80         temp = readfds;81         val = select(maxfd+1,&temp,NULL,NULL,NULL);82         if(val<0){83             perror("select");84             exit(1);85         }        86         //轮训判断那个文件描述符产生事件87         for(i=0;i<maxfd+1;i++){88             if(FD_ISSET(i,&temp)){89                 if(0==i){//是键盘输入产生事件90                     bzero(buf,sizeof(buf));91                     input_t = scanf("%d %s",&setfd,buf);92                     while(getchar()!='n');93                     if(input_t !=2){94                         puts("输入错误!请按格式输入:fd+空格+消息内容");95                         continue;96                     }97                     if(!FD_ISSET(setfd,&readfds)){98                         puts("输入fd号错误,没有这个链接!");99                         continue;
100                     }
101                     //发出信息
102                     do{
103                         ret = send(setfd,buf,strlen(buf),0);
104                     }while(ret<0 && EINTR==errno);
105                 }
106                 //如果是socket产生的套接字文件描述符
107                 //那就说明是要建立连接
108                 else if(sockfd == i){
109                     acceptfd = accept(sockfd,NULL,NULL);
110                     if(acceptfd < 0){
111                         perror("accept");
112                         exit(1);
113                     }
114                     //newfd加入集合
115                     FD_SET(acceptfd,&readfds);
116                     //更新maxfd(判断那个最大的文件描述符是那个)
117                     maxfd = (maxfd > acceptfd) ? maxfd : acceptfd;
118                 }
119                 else//剩下的情况就是所有的客户端对应的newfd了
120                 {
121                     bzero(buf,sizeof(buf));
122                     //i就是产生事件的客户端对应的fd
123                     //接收消息
124                     do{
125                         recv_t = recv(i,buf,sizeof(buf),0);
126                     }while(recv_t < 0 && EINTR==errno);
127                     if(recv_t <= 0){
128                         perror("客户端错误或关闭");
129                         FD_CLR(i,&readfds);
130                         close(i);
131                         maxfd = (( i == maxfd) ? (--maxfd) : maxfd);
132                     }
133                     else{
134                         printf("收到%d 消息:%sn",i,buf);
135                     }
136                 }
137             }    
138         }        
139     }            
140                  
141     close(sockfd);
142                  
143     return 0;    
144 }                
  1 /*================================================================2  *   Copyright (C) 2020 hqyj Ltd. All rights reserved.3  *                                          4  *   文件名称:02_域套接字客户端.c          5  *   创 建 者:Chens                        6  *   创建日期:2020年04月26日               7  *   描    述:                             8  *                                          9  ================================================================*/10                                             11                                             12 #include <stdio.h>                          13 #include <stdint.h>                         14 #include <sys/types.h>                      15 #include <sys/socket.h>                     16 #include <stdlib.h>                         17 #include <unistd.h>                         18 #include <arpa/inet.h>                      19 #include <string.h>                         20 #include <errno.h>                          21 #include <sys/socket.h>                     22 #include <sys/types.h>                      23 #include <sys/wait.h>                       24 #include <sys/un.h>                         25                                             26 #define  QUIT         "quit"                27 #define BACKLOG       10                    28 #define PATH          "/tmp/20021/unix_sock"29                                             30                                             31 int main(int argc, char *argv[])            32 {                                           33     int fd = -1;                            34     fd = socket(AF_LOCAL,SOCK_STREAM,0);    35                                             36     struct sockaddr_un sun;                 37     bzero(&sun,sizeof(sun));                38     sun.sun_family    = AF_LOCAL;           39     strncpy(sun.sun_path,PATH,strlen(PATH));                              40                                             41     if(access(PATH,F_OK|W_OK) <0){          42         puts("路径文件不存在或没有权限");   43         exit(1);                            44     }                                       45                                             46     if( connect(fd,(struct sockaddr*)&sun,sizeof(sun))<0){47         perror("connect");                  48         exit(1);                            49     }                                       50                                             51     puts("域套接字客户端OK!");             52                                             53                                             54     int ret =-1;                            55     int fh =-1;                             56     fd_set readfds;                         57     int maxfd =-1;                          58     struct timeval tv={1,0};                59     char buf[BUFSIZ]={};                    60                                             61     puts("准备就绪-----------");            62     while(1){                               63         FD_ZERO(&readfds);                  64         FD_SET(0,&readfds);                 65         FD_SET(fd,&readfds);                66         tv.tv_sec = 5;                      67         tv.tv_usec= 0;                      68         maxfd = fd;                         69         fh = select(maxfd+1,&readfds,NULL,NULL,&tv);70         if(fh<0){                           71             perror("select");               72             exit(1);                        73         }                                   74         if(FD_ISSET(0,&readfds)){//键盘输入了75             bzero(buf,BUFSIZ);              76             do{                             77                 ret = read(0,buf,BUFSIZ-1); 78             }while(ret<0&&EINTR==errno);    79             if(ret <0){                     80                 perror("read");             81                 continue;                   82             }                               83             if(!ret)continue;               84             if(write(fd,buf,strlen(buf))<0){85                 perror("write");            86                 exit(1);                    87             }                               88             if(!strncasecmp(buf,QUIT,strlen(QUIT))){89                 printf("***客户端退出***n");90                 break;                      91             }                               92         }                                   93         if(FD_ISSET(fd,&readfds)){//接收数据94             bzero(buf,BUFSIZ);              95             do{                             96                 ret = read(fd,buf,BUFSIZ-1);97             }while(ret<0 && EINTR==errno);  98             if(ret<0){                      99                 perror("接收");             
100                 continue;                   
101             }                               
102             if(!ret)break;                  
103             printf("已收到:%s n",buf);    
104         }                                   
105     }                                       
106     close(fd);                              
107                                             
108     return 0;                               
109 }                                           

本文发布于:2024-02-04 05:59:05,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170700533552890.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:多路   复用   poll
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23