1 1 //建立管道
2 2 mkfifo 12 13 21 23 31 32
open顺序:
cl1 读 , cl2 cl3 向 cl1写
cl2 读 , cl1 cl3 向 cl2写
cl3 读 , cl1 cl2 向 cl3写
顺序的规律就是 第i个 客户端读 其他各个客户端 ,其他的各个客户端 向 i 写 ,i 从 1 到 3.
cl1 代码:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include<unistd.h>
5 #include<sys/stat.h>
6 #include<sys/types.h>
7 #include<fcntl.h>
8 #include <sys/time.h>
9 #include<sys/select.h>
10 #include <sys/select.h>
11
12 /* According to earlier standards */
13 #include <sys/time.h>
14 #include <sys/types.h>
15 #include <unistd.h>
16
17 int main(int argc, char* argv[])//21
18 {
19
20 int fd21, fd31,fd12,fd13 ;
21 fd21 = open("21", O_RDONLY);
22 fd31 = open("31", O_RDONLY);
23
24 fd12 = open("12",O_WRONLY);
25
26 fd13 = open("13",O_WRONLY);
27 printf("OK!\n");
28
29
30 printf("OK!\n");
31 fd_set read_sets ;
32 fd_set write_sets ;
33 int iret,iwrt ;
34 char buf[1024] ;
35 struct timeval tm ;
36 while(1)
37 {
38
39 tm.tv_sec = 1 ;
40 tm.tv_usec = 0 ;
41 FD_ZERO(&read_sets);
42 FD_ZERO(&write_sets);
43
44 FD_SET(fd21, &read_sets);
45 FD_SET(fd31, &read_sets);
46 FD_SET( 0, &write_sets);
47 //FD_SET(fd12, &write_sets);
48 //FD_SET(fd13, &write_sets);
49
50 iret = select(10, &read_sets, NULL, NULL, &tm);
51 iwrt = select(10,&write_sets,NULL,NULL,&tm);
52
53 //读
54 if(iret != 0)
55 {
56 printf("active: %d\n", iret);
57
58 if(FD_ISSET(fd21, &read_sets))
59 {
60 memset(buf, 0, 1024);
61 read(fd21, buf, 1023);
62 printf("from 2: %s\n", buf);
63 }
64 if(FD_ISSET(fd31, &read_sets))
65 {
66 memset(buf, 0, 1024);
67 read(fd31, buf, 1023);
68 printf("from 3: %s\n", buf);
69 }
70 }
71
72
73 // write
74 if(iwrt != 0)
75 {
76 printf("active: %d\n", iwrt);
77 if(FD_ISSET( 0 /*fd12*/, &write_sets))
78 {
79 memset(buf, 0, 128);
80 read(0, buf, 127) ;
81 write(fd12, buf, strlen(buf));
82 write(fd13, buf, strlen(buf));
83 }
84 /*if(FD_ISSET(fd13, &write_sets))
85 {
86 memset(buf, 0, 128);
87 read(0, buf, 127) ;
88 write(fd13, buf, strlen(buf));
89 }*/
90 }
91
92 }
93 return 0 ;
94 }
cl2 代码:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include<unistd.h>
5 #include<sys/stat.h>
6 #include<sys/types.h>
7 #include<fcntl.h>
8 #include<sys/select.h>
9 int main(int argc, char* argv[])//21
10 {
11 int fd12, fd32,fd21,fd23 ;
12 fd21 = open("21",O_WRONLY);
13
14 fd12 = open("12", O_RDONLY);
15 fd32 = open("32", O_RDONLY);
16
17 fd23 = open("23",O_WRONLY);
18
19
20 fd_set read_sets ,write_sets ;
21 int iret ,iwrt;
22 char buf[1024] ;
23 struct timeval tm ;
24 while(1)
25 {
26
27 tm.tv_sec = 1 ;
28 tm.tv_usec = 0 ;
29 FD_ZERO(&read_sets);
30 FD_ZERO(&write_sets);
31 FD_SET(fd12, &read_sets);
32 FD_SET(fd32, &read_sets);
33 FD_SET( 0, &write_sets);
34 //FD_SET(fd21,&write_sets);
35 //FD_SET(fd23,&write_sets);
36
37 iret = select(10, &read_sets, NULL, NULL, &tm);
38 iwrt = select(10,&write_sets,NULL,NULL,&tm);
39
40 if(iret != 0)
41 {
42 printf("active: %d\n", iret);
43
44 if(FD_ISSET(fd12, &read_sets))
45 {
46 memset(buf, 0, 1024);
47 read(fd12, buf, 1023);
48 printf("from 1: %s\n", buf);
49 }
50 if(FD_ISSET(fd32, &read_sets))
51 {
52 memset(buf, 0, 1024);
53 read(fd32, buf, 1023);
54 printf("from 3: %s\n", buf);
55 }
56 }
57
58
59 // write
60 if(iwrt != 0)
61 {
62 printf("active: %d\n", iwrt);
63 if(FD_ISSET( 0 , &write_sets))
64 {
65 memset(buf, 0, 128);
66 read(0, buf, 127) ;
67 write(fd21, buf, strlen(buf));
68 write(fd23, buf, strlen(buf));
69 }
70 /* if(FD_ISSET(fd23, &write_sets))
71 {
72 memset(buf, 0, 128);
73 read(0, buf, 127) ;
74 write(fd23, buf, strlen(buf));
75 }*/
76 }
77
78 }
79 return 0 ;
80 }
cl3 代码:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include<unistd.h>
5 #include<sys/stat.h>
6 #include<sys/types.h>
7 #include<fcntl.h>
8 #include<sys/select.h>
9 int main(int argc, char* argv[])//31
10 {
11 int fd13, fd23,fd31,fd32 ;
12 fd31 = open("31",O_WRONLY);
13
14 fd32 = open("32",O_WRONLY);
15
16 fd13 = open("13", O_RDONLY);
17 fd23 = open("23", O_RDONLY);
18
19 printf("OK!\n");
20 fd_set read_sets ,write_sets ;
21 int iret,iwrt ;
22 char buf[1024] ;
23 struct timeval tm ;
24 while(1)
25 {
26
27 tm.tv_sec = 1 ;
28 tm.tv_usec = 0 ;
29 FD_ZERO(&read_sets);
30 FD_ZERO(&write_sets);
31 FD_SET(fd13, &read_sets);
32 FD_SET(fd23, &read_sets);
33 //FD_SET(fd31,&write_sets);
34 //FD_SET(fd32,&write_sets);
35 FD_SET( 0, &write_sets);
36
37 iret = select(10, &read_sets, NULL, NULL, &tm);
38 iwrt = select(10,&write_sets,NULL,NULL,&tm);
39
40 //读
41 if(iret != 0)
42 {
43 printf("active: %d\n", iret);
44
45 if(FD_ISSET(fd13, &read_sets))
46 {
47 memset(buf, 0, 1024);
48 read(fd13, buf, 1023);
49 printf("from 1: %s\n", buf);
50 }
51 if(FD_ISSET(fd23, &read_sets))
52 {
53 memset(buf, 0, 1024);
54 read(fd23, buf, 1023);
55 printf("from 2: %s\n", buf);
56 }
57 }
58
59
60 // write
61 if(iwrt != 0)
62 {
63 printf("active: %d\n", iwrt);
64 if(FD_ISSET( 0 , &write_sets))
65 {
66 memset(buf, 0, 128);
67 read(0, buf, 127) ;
68 write(fd31, buf, strlen(buf));
69 write(fd32, buf, strlen(buf));
70 }
71 /*if(FD_ISSET(fd32, &write_sets))
72 {
73 memset(buf, 0, 128);
74 read(0, buf, 127) ;
75 write(fd32, buf, strlen(buf));
76 }*/
77 }
78 }
79
80 return 0 ;
81 }
很显然的,如果用上述的方法需要每个客户端和其他客户端都直接相邻,即完全图。
建立n个客户端通信,需要 2*((n-1)+(n-2)+(n-3)+……3+2+1) = 2*(n-1 + 1)*(n -1)/2 =n * (n-1) 根管道,
这么多的管道连接会使得代码实现变得非常冗杂、而且系统浪费资源管道。
这里,用线性链表的拓扑结构,可以解决这个问题:
1、 客户端以线性存储
2、 当 pre 发来数据时, 打印出来,并且转发给next(若next存在)。
3、 当 next 发来数据时, 打印出来,并且转发给pre(若pre存在)。
4、 当键盘发来数据时,转发给next(若next存在),转发给pre(若pre存在)。
例子:
在文件存储如下:
BuildFIFO.cpp 如下:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include<string>
5 #include<unistd.h>
6 #include<sys/stat.h>
7 #include<sys/types.h>
8 #include<fcntl.h>
9 #include <sys/time.h>
10 #include<sys/select.h>
11 using namespace std;
12 int main(int argc, char* argv[])//21
13 {
14
15 FILE* topu = fopen("topo.txt","r");
16 int fir = 1;
17 char dir[5],DIR[11];
18 string str1,str2,str ;
19 while(!feof(topu))
20 {
21 fscanf(topu ,"%s\n",dir);
22 str1 = dir;
23 if(fir)
24 {
25 fir =0 ;
26 str2=str1;
27 continue;
28 }
29 str=str1+"T"+str2;
30 strcpy(DIR,str.c_str());
31 mkfifo(DIR,0777);
32
33 str=str2+"T"+str1;
34 strcpy(DIR,str.c_str());
35 mkfifo(DIR,0777);
36 str2 = str1;
37 }
38
39 fclose(topu);
40
41 return 0;
42 }
只需要每个相邻的客户端 读写顺序相反就能解决了
如下:
1 if(count & 1== 1) //判断节点的位置是奇数 还是 偶数 ,如果是 奇数 就 先读后写
2 {
3 if(strcmp("-1",pre->val)!=0)
4 {
5
6 fdReadFromPre = My_Open(pre->val,p->val,0);
7 fdWriteToPre = My_Open(p->val,pre->val,1);
8 }
9
10 if(p->next!=NULL)
11 {
12 fdReadFromNext = My_Open(p->next->val,p->val,0);
13 fdWriteToNext = My_Open(p->val,p->next->val,1);
14 }
15 }
16 else //如果是偶数,先写后读
17 {
18 if(strcmp("-1",pre->val)!=0)
19 {
20 fdWriteToPre = My_Open(p->val,pre->val,1);
21 fdReadFromPre = My_Open(pre->val,p->val,0);
22 }
23
24 if(p->next!=NULL)
25 {
26 fdWriteToNext = My_Open(p->val,p->next->val,1);
27 fdReadFromNext = My_Open(p->next->val,p->val,0);
28 }
29
30 }
这里只发 cl1.cpp
(
其他客户端就是
1 while( strcmp("1",p->val)!=0)
1 char tembuf[1024] = "Form1 :";
这两句代码不一样而已
)
如下:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include<unistd.h>
5 #include<sys/stat.h>
6 #include<sys/types.h>
7 #include<fcntl.h>
8 #include <sys/time.h>
9 #include<sys/select.h>
10
11
12 #define fdNULL -9999
13
14 struct node
15 {
16 char val[5];
17 node* next;
18 };
19
20 int My_Open(char A[],char B[],int type)
21 {
22 char Cstr[11];
23 memset( Cstr, '\0', sizeof(Cstr) );
24 strcat(Cstr,A);
25 strcat(Cstr,"T");
26 strcat(Cstr,B);
27 if(type == 0) return open(Cstr, O_RDONLY);
28 else return open(Cstr, O_WRONLY);
29 }
30
31
32 int main(int argc, char* argv[])//21
33 {
34
35 FILE* topu = fopen("/home/soso/Desktop/1-30/LineSelect/topo.txt","r");
36 char a[5];
37
38 node* L = (node*)calloc(1, sizeof(node)); //save topo
39 strcpy(L->val,"-1");
40 L->next = NULL;
41 node* tem , *p ,*pre;
42 p=L;
43 while(!feof(topu))
44 {
45 fscanf(topu ,"%s\n",a);
46 tem= (node*)calloc(1, sizeof(node));
47 strcpy(tem->val,a);
48 tem->next = NULL;
49 p->next=tem;
50 p=p->next;
51 }
52 fclose(topu);
53
54 pre=L;
55 p= L->next;
56 int count = 1;
57 while( strcmp("1",p->val)!=0)
58 {
59 p=p->next;
60 pre=pre->next;
61 ++count;
62 }
63
64 int fdReadFromPre,fdReadFromNext,fdWriteToPre,fdWriteToNext ;
65 fdReadFromPre=fdReadFromNext=fdWriteToPre=fdWriteToNext=fdNULL;
66 if(count & 1== 1) //判断节点的位置是奇数 还是 偶数 ,如果是 奇数 就 先读后写
67 {
68 if(strcmp("-1",pre->val)!=0)
69 {
70
71 fdReadFromPre = My_Open(pre->val,p->val,0);
72 fdWriteToPre = My_Open(p->val,pre->val,1);
73 }
74
75 if(p->next!=NULL)
76 {
77 fdReadFromNext = My_Open(p->next->val,p->val,0);
78 fdWriteToNext = My_Open(p->val,p->next->val,1);
79 }
80 }
81 else //如果是偶数,先写后读
82 {
83 if(strcmp("-1",pre->val)!=0)
84 {
85 fdWriteToPre = My_Open(p->val,pre->val,1);
86 fdReadFromPre = My_Open(pre->val,p->val,0);
87 }
88
89 if(p->next!=NULL)
90 {
91 fdWriteToNext = My_Open(p->val,p->next->val,1);
92 fdReadFromNext = My_Open(p->next->val,p->val,0);
93 }
94
95 }
96
97 printf("OK!\n");
98
99 fd_set read_sets ;
100 fd_set write_sets ;
101 int iret,iwrt ;
102 char buf[1024] ;
103 struct timeval tm ;
104 while(1)
105 {
106
107 tm.tv_sec = 1 ;
108 tm.tv_usec = 0 ;
109 FD_ZERO(&read_sets);
110 FD_ZERO(&write_sets);
111 if(fdReadFromPre != fdNULL)
112 FD_SET(fdReadFromPre, &read_sets);
113 if(fdReadFromNext != fdNULL)
114 FD_SET(fdReadFromNext, &read_sets);
115 FD_SET( 0, &write_sets);
116
117
118 iret = select(10, &read_sets, NULL, NULL, &tm);
119 iwrt = select(10,&write_sets,NULL,NULL,&tm);
120
121 //读
122 if(iret != 0)
123 {
124
125 if(FD_ISSET(fdReadFromPre, &read_sets))
126 {
127 memset(buf, 0, 1024);
128 read(fdReadFromPre, buf, 1023);
129 if(fdWriteToNext!=fdNULL) //把从pre读过来的数据转发到next去
130 write(fdWriteToNext, buf, strlen(buf));
131 printf("%s\n" ,buf);
132 }
133 if(FD_ISSET(fdReadFromNext, &read_sets))
134 {
135 memset(buf, 0, 1024);
136 read(fdReadFromNext, buf, 1023);
137 if(fdWriteToPre!=fdNULL) //把从next读过来的数据转发到pre去
138 write(fdWriteToPre, buf, strlen(buf));
139 printf("%s\n", buf);
140 }
141 }
142
143
144 // write
145 if(iwrt != 0)
146 {
147
148 if(FD_ISSET( 0 , &write_sets))
149 {
150 memset(buf, 0, 128);
151 read(0, buf, 127) ;
152 char tembuf[1024] = "Form1 :";
153 strcat(tembuf,buf);
154 if(fdWriteToNext!=fdNULL) //把从键盘输入的数据向next、pre 转发
155 write(fdWriteToNext, tembuf, strlen(tembuf));
156 if(fdWriteToPre!=fdNULL)
157 write(fdWriteToPre, tembuf, strlen(tembuf));
158 }
159 }
160
161 }
162 return 0;
163 }
1、在topo.txt 添加 客户名 再 换行
2、再按一下 已经生成的 BuildFIFO 可执行文件,及自动生成所需的管道
3、vim 出客户端,代码只需 改动两处(见5) 便可以完成客户端的添加。
线性拓扑结构有个很大的缺陷
如图:
客户端1 发送消息,要经过 3、2 的转发才能到达 4。当客户端数量很大时,链表前部和后部之间的通信的延迟会很大。
如果改进,用树形拓扑机构就会很大的缓解这个问题。
如图 为Zhu客户端键盘输入数据:
在文件topo.txt 中以类似于邻接的方式存储:
topo文件格式为:
顶点 节点个数 节点1 节点2 ……
如图:
客户端读取文件后的邻接表存储代码:
1 map<string,bool> visit;
2
3 struct TreeLine
4 {
5 vector<string> TreeNode;
6 int level; //层号
7 };
8
9
10 map<string,TreeLine> Tree;
1 FILE* topu = fopen("topo.txt","r");
2 int fir = 1;
3 int i,j;
4 char strtem[5],strtem2[5],tem,Lval[5];
5 int num;
6 while(!feof(topu))
7 {
8 fscanf(topu ,"%s %d",strtem,&num);
9 if(fir) //记录第一个客户端的名称
10 {
11 fir = 0;
12 strcpy(Lval,strtem);
13 }
14
15
16 TreeLine TemLine;
17 for(int i =0 ;i< num;i++)
18 {
19 fscanf(topu," %s",strtem2);
20 TemLine.TreeNode.push_back(strtem2);
21 }
22 fgetc(topu);
23
24 Tree[strtem]=TemLine;
25 visit[strtem] = false; //初始化访问位
26 }
27 fclose(topu);
3、DFS来标注奇偶层号,判断open顺序(只要奇偶层顺序相反)
1 void DFS(string val,int level)
2 {
3 visit[val] = true ;
4 Tree[val].level = level;
5 //cout<<val<<":"<<level<<" "<<Tree[val].TreeNode.size()<<endl;
6 int i;
7 for(i = 0;i<Tree[val].TreeNode.size();++i)
8 {
9 if(visit[Tree[val].TreeNode[i]] == false)
10 DFS(Tree[val].TreeNode[i],level+1);
11 }
12 }
1 int level = 1;
2 DFS(Lval,level);
3
4 vector<int> fdReadOpen,fdWriteOpen;
5
6
7 string TemString;
8 if(Tree[UserName].level & 1 == 1) //判断层号 奇数先读后写
9 {
10 for(i= 0 ;i<Tree[UserName].TreeNode.size();++i)
11 {
12 TemString=Tree[UserName].TreeNode[i]+"TO"+UserName;
13 fdReadOpen.push_back(open(TemString.c_str(), O_RDONLY));
14 }
15
16 for(i= 0 ;i<Tree[UserName].TreeNode.size();++i)
17 {
18 TemString = UserName;
19 TemString+="TO"+Tree[UserName].TreeNode[i];
20 fdWriteOpen.push_back(open(TemString.c_str(),O_WRONLY));
21 }
22
23 }
24 else //判断层号 偶数数先写后读
25 {
26 for(i= 0 ;i<Tree[UserName].TreeNode.size();++i)
27 {
28 TemString = UserName;
29 TemString+="TO"+Tree[UserName].TreeNode[i];
30 fdWriteOpen.push_back(open(TemString.c_str(),O_WRONLY));
31 }
32
33 for(i= 0 ;i<Tree[UserName].TreeNode.size();++i)
34 {
35 TemString=Tree[UserName].TreeNode[i]+"TO"+UserName;
36 fdReadOpen.push_back(open(TemString.c_str(), O_RDONLY));
37 }
38 }
这次用了宏定义,每个客户端只需修改:
1 #define UserName "Ye"
其他代码都相同。
这里分析客户端 Ye 的代码:
1 #include <vector>
2 #include<map>
3 #include<string>
4 #include<iostream>
5 #include<stdio.h>
6 #include<stdlib.h>
7 #include<string.h>
8 #include<unistd.h>
9 #include<sys/stat.h>
10 #include<sys/types.h>
11 #include<fcntl.h>
12 #include <sys/time.h>
13 #include<sys/select.h>
14 using namespace std;
15
16 #define MaxSize 10000
17
18 #define UserName "Ye"
19
20 map<string,bool> visit;
21
22 struct TreeLine
23 {
24 vector<string> TreeNode;
25 int level; //层号
26 };
27
28
29 map<string,TreeLine> Tree;
30
31 void DFS(string val,int level)
32 {
33 visit[val] = true ;
34 Tree[val].level = level;
35 //cout<<val<<":"<<level<<" "<<Tree[val].TreeNode.size()<<endl;
36 int i;
37 for(i = 0;i<Tree[val].TreeNode.size();++i)
38 {
39 if(visit[Tree[val].TreeNode[i]] == false)
40 DFS(Tree[val].TreeNode[i],level+1);
41 }
42 }
43
44
45
46 int main(int argc, char* argv[])
47 {
48
49 FILE* topu = fopen("topo.txt","r");
50 int fir = 1;
51 int i,j;
52 char strtem[5],strtem2[5],tem,Lval[5];
53 int num;
54 while(!feof(topu))
55 {
56 fscanf(topu ,"%s %d",strtem,&num);
57 if(fir) //记录第一个客户端的名称
58 {
59 fir = 0;
60 strcpy(Lval,strtem);
61 }
62
63
64 TreeLine TemLine;
65 for(int i =0 ;i< num;i++)
66 {
67 fscanf(topu," %s",strtem2);
68 TemLine.TreeNode.push_back(strtem2);
69 }
70 fgetc(topu);
71
72 Tree[strtem]=TemLine;
73 visit[strtem] = false; //初始化访问位
74 }
75 fclose(topu);
76
77 int level = 1;
78 DFS(Lval,level);
79
80 vector<int> fdReadOpen,fdWriteOpen;
81
82
83 string TemString;
84 if(Tree[UserName].level & 1 == 1) //判断层号 奇数先读后写
85 {
86 for(i= 0 ;i<Tree[UserName].TreeNode.size();++i)
87 {
88 TemString=Tree[UserName].TreeNode[i]+"TO"+UserName;
89 fdReadOpen.push_back(open(TemString.c_str(), O_RDONLY));
90 }
91
92 for(i= 0 ;i<Tree[UserName].TreeNode.size();++i)
93 {
94 TemString = UserName;
95 TemString+="TO"+Tree[UserName].TreeNode[i];
96 fdWriteOpen.push_back(open(TemString.c_str(),O_WRONLY));
97 }
98
99 }
100 else //判断层号 偶数数先写后读
101 {
102 for(i= 0 ;i<Tree[UserName].TreeNode.size();++i)
103 {
104 TemString = UserName;
105 TemString+="TO"+Tree[UserName].TreeNode[i];
106 fdWriteOpen.push_back(open(TemString.c_str(),O_WRONLY));
107 }
108
109 for(i= 0 ;i<Tree[UserName].TreeNode.size();++i)
110 {
111 TemString=Tree[UserName].TreeNode[i]+"TO"+UserName;
112 fdReadOpen.push_back(open(TemString.c_str(), O_RDONLY));
113 }
114 }
115
116
117
118
119 printf("OK!\n");
120
121 fd_set read_sets ;
122 fd_set write_sets ;
123 int iret,iwrt ;
124 char buf[1024] ;
125 struct timeval tm ;
126 while(1)
127 {
128
129 tm.tv_sec = 1 ;
130 tm.tv_usec = 0 ;
131 FD_ZERO(&read_sets);
132 FD_ZERO(&write_sets);
133 for(i=0;i<fdReadOpen.size();i++)
134 FD_SET(fdReadOpen[i], &read_sets);
135 FD_SET( 0, &write_sets);
136
137 iret = select(1023, &read_sets, NULL, NULL, &tm);
138 iwrt = select(1023,&write_sets,NULL,NULL,&tm);
139
140 //读
141 if(iret != 0)
142 {
143
144 for(i=0;i<fdReadOpen.size();i++) //遍历ReadOpen
145 {
146 if(FD_ISSET(fdReadOpen[i], &read_sets)) //当收到ReadOpen[i]时
147 {
148 memset(buf, 0, 1024);
149 read(fdReadOpen[i], buf, 1023);
150 printf("%s\n" ,buf); //打印出来
151 for(j=0;j<fdWriteOpen.size();j++) //向其他客户端转发
152 {
153 if(j != i) //AtoB 和 BtoA 的fdOpen存储位置是对应的
154 write(fdWriteOpen[j], buf, strlen(buf));
155 }
156 }
157 }
158 }
159
160
161 // write
162 if(iwrt != 0)
163 {
164 if(FD_ISSET( 0 , &write_sets))
165 {
166 memset(buf, 0, 128);
167 read(0, buf, 127) ;
168 char tembuf[1024] = UserName;
169 strcat(tembuf," :");
170 strcat(tembuf,buf);
171 for(i =0 ;i< fdWriteOpen.size();i++)
172 write(fdWriteOpen[i], tembuf, strlen(tembuf));
173 }
174 }
175
176 }
177
178
179 return 0;
180 }
1、按照输入格式在topo.txt 添加
2、再按一下 已经生成的 BuildFIFO 可执行文件,及自动生成所需的管道
3、vim 出客户端,代码只需 改动一处(见3) 便可以完成客户端的添加。