Unix-Linux编程实践教程——第十一章
来源:互联网 发布:手机隔墙听软件 编辑:程序博客网 时间:2024/05/29 04:33
章节概要
本章节介绍进程间管道通信以及套接字SOCKET编程
mylinux.h
/********************************************************* > File Name: mylinux.h > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月16日 星期一 13时49分36秒 *********************************************************/#ifndef _MYLINUX_H_#define _MYLINUX_H_#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<wait.h>#include<signal.h>#include<string.h>#include<sys/types.h>#include<sys/stat.h>#include<sys/socket.h>#include<netinet/in.h>#include<netdb.h>#include<fcntl.h>#include<time.h>#include<utmp.h>#define oops(m,x) {perror(m);exit(x);}void fatal(char* mess){ fprintf(stderr,"Error: %s\n",mess); exit(1);}#endif
tinybc.c
/********************************************************** > File Name: tinybc.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月16日 星期一 13时25分46秒 **********************************************************/#include "mylinux.h"//这里要理清管道的出入void be_dc(int in[2],int out[2]){ //管道读取端连接到stdin if(dup2(in[0],0)==-1) oops("dc,cannot redirect stdin",3); close(in[0]); close(in[1]); //管道输入端连接到stdout if(dup2(out[1],1)==-1) oops("dc,cannot redirect stdout",4); close(out[1]); close(out[0]); execlp("dc","dc","-",NULL); oops("Cannot run dc",5);}void be_bc(int todc[2],int fromdc[2]){ int num1,num2; char operation[BUFSIZ],message[BUFSIZ]; FILE *fpout,*fpin; close(todc[0]); //won't read from pipe to dc close(fromdc[1]);//won't write to pipe from dc fpout = fdopen(todc[1],"w"); fpin = fdopen(fromdc[0],"r"); if(fpout==NULL||fpin==NULL) fatal("Error convering pipes to streams"); while(printf("tinybc:"),fgets(message,BUFSIZ,stdin)!=NULL){ if(sscanf(message,"%d%[-+*/^%]%d",&num1,operation,&num2)!=3){ printf("syntax error\n"); continue; } if(fprintf(fpout,"%d\n%d\n%c\np\n",num1,num2,*operation)==EOF) fatal("Error writing"); fflush(fpout); if(fgets(message,BUFSIZ,fpin)==NULL) break; printf("%d %c %d = %s",num1,*operation,num2,message); } fclose(fpout); fclose(fpin);}//由于管道的阻塞读取,所以会在父进程运行完be_bc后,子进程be_dc才开始执行int main(){ int pid,todc[2],fromdc[2]; if(pipe(todc)==-1||pipe(fromdc)==-1){ oops("pipe failed",1); } if((pid=fork())==-1){ oops("Cannot fork",2); } if(pid==0) be_dc(todc,fromdc); else{ be_bc(todc,fromdc); //这里的wait有什么用?——等待子进程的运算结束以及输出 wait(NULL); }}
popendemo.c
/************************************************************ > File Name: popendemo.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月16日 星期一 14时10分37秒 *********************************************************/#include "mylinux.h"int main(){ FILE *fp; char buf[100]; int i=0; fp = popen("ps|sort","r"); while(fgets(buf,100,fp)!=NULL){ printf("%3d %s",i++,buf); } pclose(fp); return 0;}
popen_ex3.c
/************************************************************ > File Name: popen_ex3.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月16日 星期一 14时13分04秒 ************************************************************/#include "mylinux.h"int main(){ FILE *fp; fp = popen("mail admin backup","w"); fprintf(fp,"Error with backup!\n"); pclose(fp); return 0;}
popen.c
/************************************************************ > File Name: popen.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月16日 星期一 14时22分49秒 ************************************************************/#include "mylinux.h"#define READ 0#define WRITE 1//popen的简单实现FILE* popen(const char *command,const char *mode){ int pfp[2],pid; int parent_end,child_end; if(*mode=='r'){ parent_end = READ; child_end = WRITE; }else if(*mode=='w'){ parent_end = WRITE; child_end = READ; }else return NULL; if(pipe(pfp)==-1){ return NULL; } if((pid=fork())==-1){ close(pfp[0]); close(pfp[1]); return NULL; } if(pid>0){ if(close(pfp[child_end])==-1){ return NULL; } return fdopen(pfp[parent_end],mode); } if(close(pfp[parent_end])==-1) exit(1); if(dup2(pfp[child_end],child_end)==-1) exit(1); if(close(pfp[child_end])==-1) exit(1); execl("/bin/sh","sh","-c",command,NULL); exit(1);}
timeserv.c
一个简单的时间服务器,socket编程参考TCP/IP详解卷一卷二
/*********************************************************** > File Name: timeserv.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月16日 星期一 14时51分43秒 ************************************************************/#include "mylinux.h"#define PORTNUM 13000#define HOSTLEN 256int main(int ac,char *av[]){ struct sockaddr_in saddr; struct hostent *hp; char hostname[HOSTLEN]; int sock_id,sock_fd; FILE *sock_fp; time_t thetime; sock_id = socket(PF_INET,SOCK_STREAM,0); if(sock_id==-1) oops("socket",1); bzero((void*)&saddr,sizeof(saddr)); //得到主机名 gethostname(hostname,HOSTLEN); hp = gethostbyname(hostname); bcopy((void*)hp->h_addr,(void*)&saddr.sin_addr,hp->h_length); //设置端口号 saddr.sin_port = htons(PORTNUM); saddr.sin_family = AF_INET; if(bind(sock_id,(struct sockaddr*)&saddr,sizeof(saddr))!=0) oops("bind",1); if(listen(sock_id,1)!=0) oops("listen",1); while(1){ sock_fd = accept(sock_id,NULL,NULL); printf("Wow!got a call!\n"); if(sock_fd==-1) oops("accept",1); sock_fp = fdopen(sock_fd,"w"); if(sock_fp==NULL) oops("fdopen",1); thetime = time(NULL); fprintf(sock_fp,"the time here is .."); fprintf(sock_fp,"%s",ctime(&thetime)); fclose(sock_fp); } return 0;}
阅读全文
0 0
- Unix-Linux编程实践教程——第十一章
- Unix-Linux编程实践教程——第二章
- Unix-Linux编程实践教程——第三章
- Unix-Linux编程实践教程——第四章
- Unix-Linux编程实践教程——第五章
- Unix-Linux编程实践教程——第六章
- Unix-Linux编程实践教程——第七章
- Unix-Linux编程实践教程——第八章
- Unix-Linux编程实践教程——第九章
- Unix-Linux编程实践教程——第十章
- Unix-Linux编程实践教程——第十二章
- Unix-Linux编程实践教程——第十三章
- Unix-Linux编程实践教程——第十四章
- Unix-Linux编程实践教程——第十五章
- Unix/Linux编程实践教程
- Unix/Linux编程实践教程
- Unix-linux编程实践教程
- Unix/Linux 编程实践教程 第6章 笔记
- VMware 虚拟化编程(12) — VixDiskLib Sample 程序使用
- php程序死循环导致502报错
- 深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接
- C 循环
- 微信小程序使用swiper实现侧滑功能
- Unix-Linux编程实践教程——第十一章
- Netty4实战第十二章:SPDY
- zookeeper安装过程
- Pip 国内源的使用
- Java并发编程之原子变量
- 命令模式
- Akka(29): Http:Server-Side-Api,Low-Level-Api
- JavaWeb之Jetty和Tomcat内嵌服务器实现
- 数组如何模拟链表