博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux基础——通过select实现简单的服务器与客户端
阅读量:6690 次
发布时间:2019-06-25

本文共 3694 字,大约阅读时间需要 12 分钟。

在这里,我们还是需要一个管道,只不过,我们只需这一个管道,即可知道,客户端有哪些上线、对话、下线等。

服务器端的实现代码如下:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
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 }
View Code

在这里,当ret = -1时,我们需要判断errno是否由信号中断引起的,如果是由于人为的退出,那么程序将退出,

如果是由于信号中断,程序将再次连接信号,等待数据。

客户端的实现代码如下:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
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 }
View Code

 

转载于:https://www.cnblogs.com/gjn135120/p/4009301.html

你可能感兴趣的文章
【剑指offer】顺时针打印矩阵
查看>>
怎么将图片上传封装成指令?
查看>>
leetcode讲解--861. Score After Flipping Matrix
查看>>
聊聊JavaScript和Scala的表达式 Expression
查看>>
[原]数据科学教程: 如何使用 mlflow 管理数据科学工作流
查看>>
npm上创建发布package
查看>>
解决JS文件引用路径多层查找
查看>>
FE.TEST-前端测试初探
查看>>
超详细Dkhadoop虚拟机安装图文教程
查看>>
排序算法上——冒泡排序、插入排序和选择排序
查看>>
JAVA 8 函数式接口--Supplier
查看>>
Android HTTP
查看>>
Dockerfile多阶段构建原理和使用场景
查看>>
476-数字的补数
查看>>
七牛云赵之健:多维度融合赋能视频 AI 的实践
查看>>
Android 9 Pie震撼来袭 同步登陆WeTest
查看>>
vue+element Form键盘回车事件页面刷新解决
查看>>
CSS3中的box-sizing
查看>>
gracehttp: 优雅重启 Go 程序(热启动 - Zero Downtime)
查看>>
vue-cli中配置全局sass变量
查看>>