ite(fds[1], "world",6); //此时将会出现“断开的管道”因为子的读已经关闭了 close(fds[1]); //父关闭写 exit(0); } return 0; }
使用管道的双人聊天程序:
#include
#include
#include
#include
#include
#include
#include
#include
#include
void my_handler(int num) { wait(NULL); exit(0); } int main(int argc,char *argv[]) { int fd_w,fd_r; pid_t pid; char buf[1024]; // int *stat=NULL; fd_w=open("1to2.fifo",O_WRONLY); fd_r=open("2to1.fifo",O_RDONLY); if(pid=(fork())>0)//father send { close(fd_r); signal(17,my_handler);//17信号来处理自己; FILE *fd=fdopen(fd_w,"w"); if(fd==NULL) { perror("1to2 write failed!\n"); } while(memset(buf,0,1024),fgets(buf,1024,stdin)!=NULL) { fprintf(fd,"trudream:%s",buf);//格式化输入 fflush(fd); } fprintf(fd,"bye\n"); kill(pid,2);//杀儿子 close(fd_w); while(1); // waitpid(-1,NULL,WNOHANG); // wait(NULL); } else { close(fd_w); while(memset(buf,0,1024),read(fd_r,buf,1024)>0) { write(1,buf,strlen(buf)); while((strncmp(buf,"bye",3)==0)) { exit(0); } } close(fd_r); } return 0; }
#include
#include
#include
#include
#include
#include
#include
#include
#include
void handler(int num) { wait(NULL); exit(0); } int main(int argc,char *argv[]) { int fd_w,fd_r; pid_t pid; char buf[1024]; fd_r=open("1to2.fifo",O_RDONLY); fd_w=open("2to1.fifo",O_WRONLY); if((pid=fork())>0)//father receive { close(fd_w); signal(17,handler); while(memset(buf,0,1024),read(fd_r,buf,1024)>0) { write(1,buf,strlen(buf)); if((strncmp(buf,"bye",3))==0) { break; } } close(fd_r); kill(pid,2); while(1); // waitpid(-1,NULL,WNOHANG); // wait(NULL); } else { close(fd_r); FILE *fd=fdopen(fd_w,"w"); if(fd==NULL) { perror("2to1 write failed !\n"); } while(memset(buf,0,1024),fgets(buf,1024,stdin)!=NULL) { fprintf(fd,"麻麻的微笑:%s",buf);//格式化输入 fflush(fd); } fprintf(fd,"bye\n"); close(fd_w); } return 0; }
多人客户服务器模式聊天:
服务器端设计:永久服务器通道(服务器端只从通道读)>创建set集>服务器通道描述符加入set,用于判断是否上线#上线则读取进程号,得到对应通道名,获取读写双通道文件描述符#客户端端口已满强制关闭进程,删除通道>加入set监听变化>循环FD_ISSET()
每个读管道的变化,若变化则读取管道信息
>判断管道前三个字符是不是bye结束字符串,是,下线操作(关闭进程,关闭读写管道,清-1客户端列表)
>不是,将管道信息发送到其他管道中(监听客户端中每一个非-1的,进行发送)
//File Name: sever.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define NUM 500 typedef struct tag { int s_read; int s_write; }CLIENT_NODE; int main(int argc,char *argv[]) { if(argc!=2) { printf("No Pipename!\n"); exit(-1); } int client_pid; //客户端进程id int fd_read,fd_write;//记录管道文件描述符 char buf[1024]; char fifo_write[128];//这里写端是客户读端, 用于接受客户端创建的管道文件名 char fifo_read[128];//读端是客户写端 CLIENT_NODE client_infor[NUM];//用于放置每个聊天客户端读写管道 int fd_sever;//管道名 memset(client_infor,-1,sizeof(client_infor)); fd_sever=open(argv[1],O_RDONLY);//只读方式开发服务器管道 fd_set read_set,ready_set;//select集 FD_ZERO(&read_set); FD_SET(fd_sever,&read_set);//加入集合 struct timeva l tm; while(1) { tm.tv_sec=0; tm.tv_usec=1000;//1微妙 ready_set=read_set; select(1024,&ready_set,NULL,NULL,&tm);//轮询 if(FD_ISSET(fd_sever,&ready_set))//有人连接服务器,上线 { memset(buf,0,1024); if(read(fd_sever,buf,1024)==0) { continue; } client_pid= atoi(buf); //获取进程号 printf("client %d on!\n",client_pid); sprintf(fifo_read,"%d_write.fifo",client_pid); sprintf(fifo_write,"%d_read.fifo",client_pid); fd_write=open(fifo_write,O_WRONLY); fd_read=open(fifo_read,O_RDONLY);//>>???????? int