在这里,我们还是需要一个管道,只不过,我们只需这一个管道,即可知道,客户端有哪些上线、对话、下线等。
服务器端的实现代码如下:
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
12int errno;
13 typedef struct tag
14{
15int id;
16int fd;
17int type;
18}NODE;
19int main(int argc, constchar *argv[])
20{
21if(mkfifo(argv[1], 0666) == -1)
22 {
23 printf("创建管道失败!!n");
24 exit(1);
25 }
26 27int fd;
28 fd = open(argv[1], O_RDONLY);
29if(fd == -1)
30 {
31 printf("open error!!n");
32 exit(1);
33 }
34 NODE list[1024];
35int i;
36for(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);
46struct timeval tm;
47char buf[128];
48int ret;
49while(1)
50 {
51 ready = readset;
52 tm.tv_sec = 0;
53 tm.tv_usec = 1000;
54 ret = select(fd + 1, &ready, NULL, NULL, &tm);
55if(ret == 0)
56continue;
57elseif(ret == -1)
58 {
59if(errno == EINTR)
60continue;
61break;
62 }
63else 64 {
65 memset(buf, 0, 128);
66 read(fd, buf, 128);
67if(strncmp(buf, "on", 2) == 0)
68 {
69int sfd;
70char 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);
75int index;
76for(index = 0; index < 1024; index ++)
77 {
78if(list[index].type == OFF)
79 {
80 list[index].id = sfd;
81 list[index].fd = open(name, O_WRONLY);
82 list[index].type = ON;
83break;
84 }
85 }
86 }
87elseif(strncmp(buf, "off", 3) == 0)
88 {
89int sfd;
90 sscanf(buf + 4, "%d", &sfd);
91 printf("%d is off !!n", sfd);
92int index;
93for(index = 0; index <1024; index ++)
94 {
95if(list[index].id == sfd)
96 {
97 close(list[index].fd);
98 list[index].id = 0;
99 list[index].type = OFF;
100break;
101 }
102 }
103 }
104else105 {
106int sfd;
107 sscanf(buf + 5, "%d", &sfd);
108int index;
109for(index = 0; index < 1024; index ++)
110 {
111if(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]);
119return0;
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>
9int main(int argc, constchar *argv[])
10{
11char name[128];
12 memset(name, 0, 128);
13 sprintf(name, "%d.fifo", getpid());
14if(mkfifo(name, 0666) == -1)
15 {
16 printf("创建管道失败!!n");
17 exit(1);
18 }
19int fd;
20 fd = open(argv[1], O_WRONLY);
21if(fd == -1)
22 {
23 printf("open error!!n");
24 exit(1);
25 }
26char buf[128];
27 memset(buf, 0, 128);
28 sprintf(buf,"on %dn",getpid());
29 write(fd, buf, strlen(name));
30int sfd;
31 sfd = open(name, O_RDONLY);
32if(sfd == -1)
33 {
34 printf("open error!!n");
35 exit(1);
36 }
37if(fork() == 0)
38 {
39if(fork() == 0)
40 {
41 close(fd);
42while(memset(buf, 0, 128), read(sfd, buf, 128))
43 printf(" >> %sn", buf);
44 close(sfd);
45 exit(1);
46 }
47 exit(1);
48 }
49 wait(NULL);
50 close(sfd);
51while(memset(buf, 0, 128), fgets(buf, 128, stdin) != NULL)
52 {
53char 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 %dn", getpid());
60 write(fd, buf, strlen(buf));
61 close(fd);
62 unlink(name);
63return0;
64 }
原文:http://www.cnblogs.com/gjn135120/p/4009301.html
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!