zoukankan      html  css  js  c++  java
  • Linux网络编程学习(七) ----- 有名管道(第四章)

    1、什么是有名管道?为什么有了管道还需要有名管道?

    有名管道是解决管道不能提供非父子进程间通信的缺陷。管道在Linux系统内部是以文件节点(inode)的形式存在,但由于其对外的不可见性(“无名”性),就无法创建新的句柄对其进行访问。而有名管道则以一种特殊的设备文件的形式存在于文件系统中,这样,有名管道不仅有了管道的通信功能,还具备普通文件的优点,也就是可以被对个进程共享,可以长期存在等。

    2、有名管道的创建

    有名管道是文件系统中的文件节点,可以通过建立文件节点的方式创建有名管道,可以用命令

    #mknod sampleFIFO p
    #mkfifo –m 0666 sampleFIFO
    

      上面两个命令时等价的,在当前的文件系统中创建一个名字为sampleFIFO的有名管道。文件信息中p指示符可以迅速辨认出有名管道,如

    #ls -l
    prw-r--r-- 1 root root 0 May 14 16:25 sampleFIFO|
    

      可以看到sampleFIFO是有名管道。

    在C语言中是用mknod()创建有名管道,函数声明是int mknod( char *pathname, mode_t mode, dev_t dev);

    例如:

    mknod(“/tmp/sampleFIFO”,s_IFIFO|0666,0)
    

      这条语句建立了一个名为“/tmp/sampleFIFO”的有名管道,读写权限是0666,第三个参数默认填0

    3、有名管道的I/O使用

    可以用操作文件流fopen()和fclose()来打开一个有名管道,下面是server方的例子:

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <linux/stat.h>
    #define FIFO_FILE "sampleFIFO"
    int main(void)
    {
    	FILE *fp;
    	char readbuf[80];
    	/* Create the FIFO if it does not exist */
    	umask(0);
    	/*在文件系统中创建有名管道*/
    	mknod(FIFO_FILE, S_IFIFO|0666, 0);
    	while(1)
    	{
    		/*打开有名管道*/
    		fp = fopen(FIFO_FILE, "r");
    		/*从有名管道中读取数据*/
    		fgets(readbuf, 80, fp);
    		printf("Received string: %s
    ", readbuf);
    		/*关闭有名管道*/
    		fclose(fp);
    	}
    	return(0);
    }
    

      由于有名管道自动支持进程阻塞,所有我们可以让这个server在后台运行

    #fifoserver &
    

      然后运行client程序

    #include <stdio.h>
    #include <stdlib.h>
    #define FIFO_FILE "sampleFIFO"
    int main(int argc, char *argv[])
    {
    	FILE *fp;
    	if ( argc != 2 ) 
    	{
    		printf("USAGE: fifoclient [string]
    ");
    		exit(1);
    	}
    	/*打开有名管道*/
    	if((fp = fopen(FIFO_FILE, "w")) == NULL) 
    	{
    		perror("fopen");
    		exit(1);
    	}
    	/*向有名管道中写入数据*/
    	fputs(argv[1], fp);
    	/*关闭有名管道*/
    	fclose(fp);
    	return(0);
    }
    

      由于有名管道的自动阻塞特性,server打开一个有名管道准备读入时,server会被阻塞以等待其他进程在有名管道写入数据。

    4、tips

    1)有名管道必须要有读和写两个进程端,,如果试图向一个没有读入端进程的有名管道写入数据,则会产生SIGPIPE信号

    2)管道操作的独立性,也就意味着这个操作不会因为任务原因中断,Linux系统中,一次独立的读/写操作只能传送4096个字节数据,若超过了上限,需要分多次传输,否则可能会被其他进程的写操作打断,可能把数据插入了该进程写入管道的数据序列中造成数据混乱。这点特别注意

  • 相关阅读:
    短信平台接口调用方法参考
    C#部分类与部分方法
    Oracle表字段类型更改的一个经验
    ueditor的上传文件漏洞(c#)
    判断一个文件是否是指定后缀名的文件
    利用FluorineFx的ByteArray上传图片
    FluorineFx 播放FLV 时堆棧溢出解决 FluorineFx NetStream.play 并发时,无法全部连接成功的解决办法
    Flex数据交互之Remoting[转]
    fluorinefx使用手册
    SharedObject使用:在FluorineFx.net与Flex中使用共享对象维护在线用户列表实例【转】
  • 原文地址:https://www.cnblogs.com/xqn2017/p/8901380.html
Copyright © 2011-2022 走看看