0.摘要
概念和技巧
-客户/服务器模型
-用管道来双向通信
-协同进程(coroutines)
-文件/进程的相似性
-什么是socket,为什么需要socket,如何使用socket
-网路服务
-用socket编写客户/服务器程序
相关系统调用和函数
-fdopen
-popen
-socket
-bind
-listen
-accept
-connect
1.一个简单的传输数据的结构
如图所示
-(1,2)磁盘/设备文件
用open命令连接,用read和write传送数据。
-管道
用pipe命令创建,用fork共享,用read和write传送数据
-Sockets
用socket,listen和connect连接,用read和write传送数据
接下里书中从bc出发来讲解管道通信与dc的交互。
2.bc:Unix中使用的计算器
1.bc并不是一个计算器
它是与一个dc的系统调用,通过管道来通信的,dc是一个基于栈的计算器.
2.从bc方法中得到的思想
(1)客户/服务器模型
bc/dc程序对是客户/服务器模型设计的一个实例。它们之间使用stdin和stdout进行通信
(2)双向通信
传统的Unix管道只是单向传送数据,但是bc和dc之间需要双向传递。
(3)永久性服务
bc只是让单一的dc进程处于运行状态,这不同于shell程序。bc程序持续不断和一个dc的同一个实例进行通信,把用户的输入转换成命令传给dc。
bc/dc对被称为协同进程(coroutines)以用来区别子程序(subroutines)。两种程序持续运行,当其中一个程序完成自己的工作后将把控制权传给另一个程序。bc的任务是分析输入及打印,而dc则负责计算。
2.1编写bc: pipe,fork,dup,exec
(1)创建两个管道
(2)创建一个进程来运行dc
(3)在新创建的过程中,重定向标准输入和标准输出到管道,然后运行exec dc
(4)在父进程中,读取并分析用户的输入,将命令传给dc,dc读取响应,并把响应传给用户。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/wait.h>
#define oops(m,x) {perror(m);exit(x);}
void be_bc(int *,int*);
void be_dc(int *,int*);
void main()
{
int pid, todc[2], fromdc[2];/*equipment*/
/*make two pipes*/
if(pipe(todc) == -1||pipe(fromdc) ==-1)
oops("pipe failed",1);
/*get a process for user interface*/
if((pid =fork())==-1)
oops("cannot fork",2);
if(pid == 0) /*child is dc*/
be_dc(todc,fromdc);
else{
be_bc(todc,fromdc); /*parent is ui*/
wait(NULL);