《unix高级环境编程》高级 I/O——STREAMS(流)
来源:互联网 发布:谜一样的双眼知乎 编辑:程序博客网 时间:2024/06/16 04:20
STREAMS(流)是系统 V 提供的构造内核设备驱动程序和网络协议包的一种通用方法。流在用户进程和设备驱动程序之间提供了一条全双工通路,下面是流在用户进程和设备驱动程序之间的流图:写到流首的数据将顺流而下传送,由设备驱动程序读到的数据则逆流向上传送;
STREAMS 消息
STREAMS 的所有输入和输出都是基于消息,流首和用户进程使用 read、write、ioctl、getmsg、getpmsg、putmsg 和 putpmsg 交换信息。在流首、各处理模块和设备驱动程序之间,消息可顺流而下,也可逆流而上。
在用户进程和流首之间,消息由以下几部分组成:消息类型、控制信息和数据;其中控制信息和数据由以下结构指定:
- struct strbuf
- {
- int maxlen; /* size of buffer */
- int len; /* number of bytes currently in buffer */
- char *buf; /* pointer to buffer */
- };
当使用putmsg 或 putpmsg 发送消息时,len 指定缓冲区中数据的字节数;当使用 getmsg 或 getpmsg 接收消息时,maxlen 指定缓冲区长度,而 len 则由内核设置为存放缓冲区的数据量;消息长度允许为0,len 为 -1 时说明没有控制信息和数据。
在我们所使用的函数(read,write,getmsg,getpmsg,putmsg 和 putpmsg)中,只涉及三种消息类型,他们是:
- M_DATA(I/O 的用户数据);
- M_PROTO(协议控制信息);
- M_PCPROTO(高优先级协议控制信息);
流中的消息都有一个排队优先级:
- 高优先级消息(最高优先级);
- 优先级波段消息;
- 普通消息(最低优先级);
普通信消息是优先级波段为 0 的消息,优先级波段可在 1~255 之间,波段愈高,优先级也愈高,在任何时刻流首只有一个高优先级消息排队,若在流首读队列已有一个高优先级消息,则另外的高优先级消息会被丢弃。
putmsg 和 putpmsg 函数
putmsg 和 putpmsg 函数用于 STREAMS 消息写至流中,这两个函数的区别是后者允许对消息指定一个优先级波段。
- /* 流 */
- /*
- * 函数功能:将STREAMS消息写至流;
- * 返回值:若成功则返回0,若出错则返回-1;
- * 函数原型:
- */
- #include <stropts.h>
- int putmsg(int filedes, const struct strbuf *ctlptr, const struct strbuf *datptr, int flags);
- int putpmsg(int filedes, const struct strbuf *ctlptr, const struct strbuf *datptr, int band, int flags);
- /*
- * 说明:
- * 对流使用write函数等价于不带任何控制信息、flags为0的putmsg函数;
- * 这两函数可以产生三种不同优先级的消息:普通、优先级波段和高优先级;
- */
STREAMS 的 ioctl 操作
ioctl 函数如下:
- /* Perform the I/O control operation specified by REQUEST on FD.
- One argument may follow; its presence and type depend on REQUEST.
- Return value depends on REQUEST. Usually -1 indicates error. */
- int ioctl (int __fd, unsigned long int __request, ...) ;
- /*
- * 函数功能:判断描述符是否引入一个流;
- * 返回值:若为STREAMS设备则返回1,否则返回0;
- * 函数原型:
- */
- #include <stropts.h>
- int isastream(int filedes);
- /*
- * 说明:
- * 该函数是通过ioctl函数来进行的,可有如下实现:
- */
- #include <stropts.h>
- #include <unistd.h>
- int isastream(int fd)
- {
- return(ioctl(fd, I_CANPUT, 0) != -1);
- }
写模式
可以使用两个 ioctl 命令取得和设置一个流的写模式,如果将 request 设置为 I_GWPORT,第三个参数设置为指向一个整型变量的指针,则该流的当前写模式在该整型变量中返回。如果将 request 设置为 I_SWPORT,第三个参数是一个整型值,则其值成为该流新的写模式,我们可以先获取当前写模式值,然后修改它,则进行设置。目前只定义了两个写模式值。
- SNDZERO:对管道和 FIFO 的0长度 write 会造成顺流传送一个0长度消息。按系统默认,0长度写不发送消息。
- SNDPIPE:在流上已出错后,若调用 write 和 putmsg,则向调用进程发送 SIGPIPE 信息。
读模式
读STREAMS设备有两个潜在的问题:
- 如果读到流中消息的记录边界将会怎样?
- 如果调用 read,而流中下一个消息由控制信息又将如何?
调用 ioctl 时,若将 request 设置成 I_GRDOPT,第三个参数又是指向一个整型单元的指针,则对该流的当前读模式在该整型单元中返回。如果将 request 设置为 I_SRDOPT,第三个参数是整型值,则将该流的读模式设置为该值。读模式可由下列三个常量指定:
- RNORM:普通,字节流模式,如上述这是默认模式。
- RMSGN:消息不丢弃模式,read从流中取数据知道读到所要求的字节数,或者到达消息边界。如果某次read只用了消息的一部分,则其余部分仍留在流中,以供下一次读。
- RMSGD:消息丢弃模式,这与不丢弃模式的区别是,如果某次只用了消息的一部分,则余下部分就被丢弃,不再使用。
在读模式中还可指定另外三个变量,以便设置在读到流中包含协议控制信息的消息时read的处理方法:任一时刻,智能设置一种消息读模式和一种协议读模式,默认读模式是:(RNORM | RPROTNORM)。
- RPROTNORM:协议-普通模式。read 出错返回,errno 设置为 EBADMSG。这是默认模式。
- RPROTDAT:协议-数据模式。read 将控制部分作为数据返回给调用者。
- RPROTDIS:协议-丢弃模式。read 丢弃消息中的控制信息。但是返回消息中的数据。
getmsg 和 getpmsg 函数
- /*
- * 函数功能:将从流读STREAMS消息;
- * 返回值:若成功则返回非负值,若出错则返回-1;
- * 函数原型:
- */
- #include <stropts.h>
- int getmsg(int filedes, const struct strbuf *ctlptr, const struct strbuf *datptr, int *flagptr);
- int getpmsg(int filedes, const struct strbuf *ctlptr, const struct strbuf *datptr, int *bandptr, int *flagptr);
- /*
- * 说明:
- * 如果flagptr指向的整型单元的值是0,则getmsg返回流首读队列中的下一个消息;
- * 如果下一个消息是最高优先级消息,则在返回时,flagptr所指向的整型单元设置为RS_HIPRI;
- * 如果只希望接收高优先级消息,则在调用getmsg之前必须将flagptr所指向的整型单元设置为RS_HIPRI;
- * getmsg可以设置待接收消息的优先级波段;
- */
- 《unix高级环境编程》高级 I/O——STREAMS(流)
- 《unix高级环境编程》高级 I/O——STREAMS(流)
- 《unix高级环境编程》高级 I/O——非阻塞 I/O
- 《unix高级环境编程》高级 I/O—— I/O 多路复用
- 《unix高级环境编程》高级 I/O—— 存储映射 I/O
- 《unix高级环境编程》高级 I/O——非阻塞 I/O
- 《unix高级环境编程》高级 I/O—— I/O 多路转接
- 《unix高级环境编程》高级 I/O—— 存储映射 I/O
- UNIX环境高级编程——文件I/O
- UNIX环境高级编程——标准I/O库
- UNIX环境高级编程——标准I/O库
- Unix环境高级编程——文件I/O
- 《UNIX环境高级编程》 —— I/O
- 《UNIX环境高级编程》读书笔记 —— 文件 I/O
- unix环境高级编程——文件i/o
- UNIX环境高级编程—文件I/O
- UNIX环境高级编程----文件I/O
- UNIX环境高级编程----标准I/O
- Nginx+Memcached+Tomcat集群配置实践(Sticky Session)
- FragmentTabHost+Fragment+ViewPager实现内外层嵌套
- 《unix高级环境编程》高级 I/O——记录锁
- 表单通过get和post方式提交数据解决乱码的方法
- java iterator
- 《unix高级环境编程》高级 I/O——STREAMS(流)
- 关 于 PV 操 作
- rabbitmq 安装负载均衡配置
- 二讲:android 是什么?android 现有成员有哪些?
- IO流 System.in BufferedReader的readLine()方法 toUpperCase()方法 equalsIgnoreCase("exit")
- Servlet<4>
- 《unix高级环境编程》高级 I/O—— I/O 多路转接
- Ubuntu系统下Hadoop 2.0.4集群安装配置
- 中科院博士教你如何查找外文文献