#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 }
用于本地间通讯,域套接字 易用性、效率还可以不错
#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小时内删除。
留言与评论(共有 0 条评论) |