首页 > 代码库 > Linux基础——通过select实现简单的服务器与客户端
Linux基础——通过select实现简单的服务器与客户端
在这里,我们还是需要一个管道,只不过,我们只需这一个管道,即可知道,客户端有哪些上线、对话、下线等。
服务器端的实现代码如下:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <sys/stat.h> 5 #include <sys/types.h> 6 #include <fcntl.h> 7 #include <sys/time.h> 8 #include <sys/select.h> 9 #include <errno.h> 10 #define ON 1 11 #define OFF 0 12 int errno; 13 typedef struct tag 14 { 15 int id; 16 int fd; 17 int type; 18 }NODE; 19 int main(int argc, const char *argv[]) 20 { 21 if(mkfifo(argv[1], 0666) == -1) 22 { 23 printf("创建管道失败!!\n"); 24 exit(1); 25 } 26 27 int fd; 28 fd = open(argv[1], O_RDONLY); 29 if(fd == -1) 30 { 31 printf("open error!!\n"); 32 exit(1); 33 } 34 NODE list[1024]; 35 int i; 36 for(i = 0; i< 1024; i ++) 37 { 38 list[i].id = 0; 39 list[i].type = OFF; 40 list[i].fd = 0; 41 } 42 fd_set readset, ready; 43 FD_ZERO(&readset); 44 FD_ZERO(&ready); 45 FD_SET(fd, &readset); 46 struct timeval tm; 47 char buf[128]; 48 int ret; 49 while(1) 50 { 51 ready = readset; 52 tm.tv_sec = 0; 53 tm.tv_usec = 1000; 54 ret = select(fd + 1, &ready, NULL, NULL, &tm); 55 if(ret == 0) 56 continue; 57 else if(ret == -1) 58 { 59 if(errno == EINTR) 60 continue; 61 break; 62 } 63 else 64 { 65 memset(buf, 0, 128); 66 read(fd, buf, 128); 67 if(strncmp(buf, "on", 2) == 0) 68 { 69 int sfd; 70 char name[128]; 71 memset(name, 0, 128); 72 sscanf(buf + 3, "%d", &sfd); 73 printf(" %d is on !!\n", sfd); 74 sprintf(name, "%d.fifo", sfd); 75 int index; 76 for(index = 0; index < 1024; index ++) 77 { 78 if(list[index].type == OFF) 79 { 80 list[index].id = sfd; 81 list[index].fd = open(name, O_WRONLY); 82 list[index].type = ON; 83 break; 84 } 85 } 86 } 87 else if(strncmp(buf, "off", 3) == 0) 88 { 89 int sfd; 90 sscanf(buf + 4, "%d", &sfd); 91 printf("%d is off !!\n", sfd); 92 int index; 93 for(index = 0; index <1024; index ++) 94 { 95 if(list[index].id == sfd) 96 { 97 close(list[index].fd); 98 list[index].id = 0; 99 list[index].type = OFF;100 break;101 }102 }103 }104 else105 {106 int sfd;107 sscanf(buf + 5, "%d", &sfd);108 int index;109 for(index = 0; index < 1024; index ++)110 {111 if(list[index].type == ON && list[index].id != sfd)112 write(list[index].fd, buf, strlen(buf));113 }114 }115 }116 }117 close(fd);118 unlink(argv[1]);119 return 0;120 }
在这里,当ret = -1时,我们需要判断errno是否由信号中断引起的,如果是由于人为的退出,那么程序将退出,
如果是由于信号中断,程序将再次连接信号,等待数据。
客户端的实现代码如下:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <sys/stat.h> 5 #include <sys/time.h> 6 #include <sys/types.h> 7 #include <sys/select.h> 8 #include <fcntl.h> 9 int main(int argc, const char *argv[])10 {11 char name[128];12 memset(name, 0, 128);13 sprintf(name, "%d.fifo", getpid());14 if(mkfifo(name, 0666) == -1)15 {16 printf("创建管道失败!!\n");17 exit(1);18 }19 int fd;20 fd = open(argv[1], O_WRONLY);21 if(fd == -1)22 {23 printf("open error!!\n");24 exit(1);25 }26 char buf[128];27 memset(buf, 0, 128);28 sprintf(buf,"on %d\n",getpid());29 write(fd, buf, strlen(name));30 int sfd;31 sfd = open(name, O_RDONLY);32 if(sfd == -1)33 {34 printf("open error!!\n");35 exit(1);36 }37 if(fork() == 0)38 {39 if(fork() == 0)40 {41 close(fd);42 while(memset(buf, 0, 128), read(sfd, buf, 128))43 printf(" >> %s\n", buf);44 close(sfd);45 exit(1);46 }47 exit(1);48 }49 wait(NULL);50 close(sfd);51 while(memset(buf, 0, 128), fgets(buf, 128, stdin) != NULL)52 {53 char msg[128];54 memset(msg, 0, 128);55 sprintf(msg, "from %d: %s",getpid(), buf);56 write(fd, msg, strlen(msg));57 }58 memset(buf, 0, 128);59 sprintf(buf, "off %d\n", getpid());60 write(fd, buf, strlen(buf));61 close(fd);62 unlink(name);63 return 0;64 }
Linux基础——通过select实现简单的服务器与客户端
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。