UNIX网络编程卷二 笔记 管道和FIFO ﹏ヽ暗。殇╰゛Y 2021-11-27 01:38 176阅读 0赞 # 第1章 管道和FIFO # ## 1.1 pipe ## int pipe(int fd[2]); 创建一个单向、半双工管道,其中fd\[0\]用于读,fd\[1\]用于写。 ## 1.2 fork ## 管道很少在单个进程内使用,一般用在两个有亲缘关系的进程间,父进程在pipe后fork,然后和子进程或子进程的后裔利用这个管道通信。 pipe(fd); if ((pid = fork()) == 0) { close(fd[0]); /*用fd[1]向父进程传递数据*/ } close(fd[1]); /*用fd[0]接收子进程传递的数据*/ ## 1.3 全双工管道 ## 可移植的创建全双工管道的方法是创建两个管道,分别负责一个方向的通信。 Linux中可以用socketpair创建一对Unix域套接字来模拟全双工管道的功能。 ## 1.4 popen和pclose ## FILE *popen(const char *cmd, const char *type); int pclose(FILE *stream); 管道的一种常见应用模式是父进程pipe+fork后,子进程重定向标准输入和输出,再exec执行一个目标程序。 popen用来简化这一系列操作,其中type用来指定读写。pclose会先关闭文件流,等到子进程执行结束后再返回子进程的退出状态。 ## 1.5 shell中创建管道 ## 当在shell中输入这样的命令时: who | sort | lp 该shell将创建三个进程和其间的两个管道,还把每个管道的fd\[0\]复制到相应进程的stdin,fd\[1\]复制到相应进程的stdout上。 ## 1.6 mkfifo ## int mkfifo(const char *pathname, mode_t mode); mkfifo用来创建一个FIFO文件,它的mode隐含了O\_CREAT | O\_EXCL。FIFO允许无亲缘关系的任意进程访问,这是和管道的最大区别。 ## 1.7 打开FIFO ## 创建FIFO后,可用open或fopen打开FIFO,打开时只能指定读或写,不能同时指定。 默认的阻塞模式下,以读或写模式打开一个FIFO时,若当前没有进程以对应的写或读模式打开FIFO,这个open将会阻塞,直到另一个进程以对应模式打开FIFO才返回。不正确的FIFO操作可能会导致死锁。 非阻塞模式下,读模式打开一个没有进程写打开的FIFO会成功返回,相反则会返回错误。 所有打开FIFO的进程都关闭FIFO后,FIFO中的剩余数据会被丢弃。 ## 1.8 设置属性 ## open打开FIFO时可指定O\_NONBLOCK标志,如: writefd = open(FIFO1, O_WRONLY | O_NONBLOCK, 0); 对描述符可以用fcntl启用O\_NONBLOCK标志。管道不能用open,因此必须用这一方法: flags = fcntl(fd, F_GETFL, 0); flag |= O_NONBLOCK; fcntl(fd, F_SETFL, flags); ## 1.9 读写管道和FIFO ## 对管道和FIFO的write总从末尾写,read总从开头读,lseek会返回错误。 阻塞模式下,read时若管道中有数据则返回,可能返回的数据比请求的少;若管道为空,如果有进程写打开该管道,则阻塞,否则返回0,表示遇到了EOF。 write时写入的数据会分成若干个最大为PIPE\_BUF字节的段,每段都是原子写入,但多个进程的多段数据写入不保证原子性。写一个没有进程读打开的FIFO会产生SIGPIPE信号。 非阻塞read和write不会影响操作的原子性,但会在需要阻塞的时候返回错误,包括: 1) read空管道。 2) write的字节数不大于PIPE\_BUF,但管道中剩余空间不足时,为了保证原子操作。 3) write的字节数大于PIPE\_BUF,管道中还有空间则写入那么多字节,否则返回错误。 ## 1.10 FIFO的单服务器多客户 ## 服务器需要一个公开的FIFO路径接收客户的请求,客户为了能接收服务器的回应,应该在请求中附上客户自己创建的FIFO路径。 并发服务器可以创建一个子进程池或子线程池来提高响应速度。 对迭代服务器的拒绝服务器型攻击是指故意发送一个不完整的请求,服务器就会陷入对剩下部分的等待中。对并发服务器的攻击则是发送大量独立请求,导致服务器fork失败。 ## 1.11 字节流和消息 ## 管道和FIFO发送的是无边界的字节流,有三种技巧用于判定消息边界: 1) 约定的终止符。 2) 显式指定长度。 3) 每次连接一个记录。 ## 1.12 管道和FIFO的限制 ## 系统的限制: 1) OPEN\_MAX 打开的最大描述符数。 2) PIPE\_BUF 原子写入的最大数据量。 FIFO是单主机上的IPC形式,不能用在NFS文件系统上。
还没有评论,来说两句吧...