《linux下的消息管道的聊天程序实现项目14401.docx》由会员分享,可在线阅读,更多相关《linux下的消息管道的聊天程序实现项目14401.docx(8页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、作者:叶建敏 QQ:230817742 2010年4月22日 15:12:56 在linux下使用管道来进行聊天的小程序1管道管道是一种种最基本的的IPC机制制,由piipe函数数创建:#incllude int ppipe(int fileedes2);调用pippe函数时时在内核中中开辟一块块缓冲区(称称为管道)用用于通信,它它有一个读读端一个写写端,然后后通过fiiledees参数传传出给用户户程序两个个文件描述述符,fiiledees0指向管道道的读端,filedes1指向管道的写端(很好记,就像0是标准输入1是标准输出一样)。所以管道在用户程序看起来就像一个打开的文件,通过read(
2、filedes0);或者write(filedes1);向这个文件读写数据其实是在读写内核缓冲区。pipe函数调用成功返回0,调用失败返回-1。开辟了管道道之后如何何实现两个个进程间的的通信呢?比如可以以按下面的的步骤通信信。1. 父进进程调用ppipe开开辟管道,得得到两个文文件描述符符指向管道道的两端。2. 父进进程调用ffork创创建子进程程,那么子子进程也有有两个文件件描述符指指向同一管管道。3. 父进进程关闭管管道读端,子子进程关闭闭管道写端端。父进程程可以往管管道里写,子子进程可以以从管道里里读,管道道是用环形形队列实现现的,数据据从写端流流入从读端端流出,这这样就实现现了进程间间
3、通信。例管道#incllude #incllude #defiine MMAXLIINE 880int mmain(voidd)int nn; int ffd2;pid_tt pidd;char lineeMAXXLINEE; if (pipee(fd) 00) perrror(pipee); exitt(1); If (pidd = ffork() 0) /* paarentt */ closse(fdd0); writee(fd1, helllo wworlddn, 12); waitt(NULLL); ellse /* chhild */ closee(fd1); n = readd(f
4、d0, linee, MAAXLINNE); writee(STDDOUT_FILEENO, linee, n); retuurn 00;使用管道有有一些限制制:两个进程通通过一个管管道只能实实现单向通通信,比如如上面的例例子,父进进程写子进进程读,如如果有时候候也需要子子进程写父父进程读,就就必须另开开一个管道道。请读者者思考,如如果只开一一个管道,但但是父进程程不关闭读读端,子进进程也不关关闭写端,双双方都有读读端和写端端,为什么么不能实现现双向通信信?管道的读写写端通过打打开的文件件描述符来来传递,因因此要通信信的两个进进程必须从从它们的公公共祖先那那里继承管管道文件描描述符。上上面的例
5、子子是父进程程把文件描描述符传给给子进程之之后父子进进程之间通通信,也可可以父进程程forkk两次,把把文件描述述符传给两两个子进程程,然后两两个子进程程之间通信信,总之需需要通过ffork传传递文件描描述符使两两个进程都都能访问同同一管道,它它们才能通通信。使用管道需需要注意以以下4种特殊情情况(假设设都是阻塞塞I/O操作作,没有设设置O_NNONBLLOCK标标志):1. 如果果所有指向向管道写端端的文件描描述符都关关闭了(管管道写端的的引用计数数等于0),而仍仍然有进程程从管道的的读端读数数据,那么么管道中剩剩余的数据据都被读取取后,再次次readd会返回0,就像读读到文件末末尾一样。2
6、. 如果果有指向管管道写端的的文件描述述符没关闭闭(管道写写端的引用用计数大于于0),而持持有管道写写端的进程程也没有向向管道中写写数据,这这时有进程程从管道读读端读数据据,那么管管道中剩余余的数据都都被读取后后,再次rread会会阻塞,直直到管道中中有数据可可读了才读读取数据并并返回。3. 如果果所有指向向管道读端端的文件描描述符都关关闭了(管管道读端的的引用计数数等于0),这时时有进程向向管道的写写端wriite,那那么该进程程会收到信信号SIGGPIPEE,通常会会导致进程程异常终止止。4. 如果果有指向管管道读端的的文件描述述符没关闭闭(管道读读端的引用用计数大于于0),而持持有管道读
7、读端的进程程也没有从从管道中读读数据,这这时有进程程向管道写写端写数据据,那么在在管道被写写满时再次次writte会阻塞塞,直到管管道中有空空位置了才才写入数据据并返回。管道的这四四种特殊情情况具有普普遍意义2.管道的的聊天小程程序1.李四端端#incllude#incllude#incllude#incllude#incllude#incllude#incllude#incllude/*李四端端*/*作者:叶建敏*/*QQ:23088177442*/int mmain() int i,rffd,wffd,leen=0,fd_iin; charr strr1288; int flagg,std
8、dinfllag; fd_sset wwritee_fd,readd_fd; struuct ttimevval nnet_ttimerr; mkfiifo(fifoo1,SS_IWUUSR|SS_IRUUSR|SS_IRGGRP|SS_IROOTH); mkfiifo(fifoo2,SS_IWUUSR|SS_IRUUSR|SS_IRGGRP|SS_IROOTH); rfd=openn(fiifo1,O_RRDONLLY); wfd=openn(fiifo2,O_WWRONLLY); if(rrfd=0 | wfdd=0) retturn 0; prinntf(这是李四四端!nn); whil
9、le(1) FD_ZEROO(&reead_ffd); FD_SET(rfd,&reaad_fdd); FD_SET(fileeno(sstdinn),&rread_fd); nett_timmer.ttv_seec=5; nett_timmer.ttv_ussec=00; memmset(str,0,siizeoff(strr); if(i=seelectt(rfdd+1,&readd_fd,NULLL,NULLL,&nnet_ttimerr)=00) ccontiinue; if(FD_IISSETT(rfdd,&reead_ffd) reead(rrfd,sstr,ssizeoof(st
10、tr); prrintff(-n); prrintff(张三三:%sn,sstr); if(FD_IISSETT(filleno(stdiin),&readd_fd) prrintff(-n); fggets(str,sizeeof(sstr),stdiin); leen=wrrite(wfd,str,strllen(sstr); closse(rffd); closse(wffd);2张三端端#incllude #incllude #incllude #incllude #incllude #incllude #incllude /*张三端端*/*作者:叶建敏*/*QQ:2308817744
11、2*/int mmain()int ii,rfdd,wfdd,lenn=0,ffd_inn;char str256;int fflag,stdiinflaag;fd_seet wrrite_fd,rread_fd;strucct tiimevaal neet_tiimer;mkfiffo(ffifo11,S_IWUSSR|S_IRUSSR|S_IRGRRP|S_IROTTH);mkfiffo(ffifo22,S_IWUSSR|S_IRUSSR|S_IRGRRP|S_IROTTH);wfd=oopen(fiffo1,O_WRRONLYY);rfd=oopen(fiffo2,O_RDDONLYY)
12、;if(wffd=00|rffd=00)retturn 0;printtf(这这是张三端!n);whilee(1)FD_ZEERO(&readd_fd);FD_SEET(rffd,&rread_fd);FD_SEET(fiilenoo(stddin),&reaad_fdd);net_ttimerr.tv_sec=5;net_ttimerr.tv_usecc=0;memseet(sttr,0,sizeeof(sstr);if(i=seleect(rrfd+11,&reead_ffd,NUULL,NNULL,&nett_timmer)=0)contiinue;if(FDD_ISSSET(rrfd,&readd_fd)read(rfd,str,sizeeof(sstr);printtf(-n);printtf(李李四:%ssn,str);if(FDD_ISSSET(ffilenno(sttdin),&reead_ffd)printtf(-nn);fgetss(strr,sizzeof(str),stddin);len=wwritee(wfdd,strr,strrlen(str);closee(wfdd);closee(rfdd);