第十三章 多种I/O复用

来源:互联网 发布:类似iebook的软件 编辑:程序博客网 时间:2024/06/08 02:40

TCP/IP网络编程》尹圣雨 P211-P225

send & recv函数


Linux中的send & recv

#include<sys/socket.h>  ssize_t send(int sockfd, const void *buf,size_t nbytes,int flags);

成功时返回发送的字节数,失败时返回-1.


#include<sys/socket.h>  ssize_t recv(int sockfd,  void *buf,size_t nbytes,int flags); 

成功时返回接收的字节数(收到EOF返回0),失败时返回-1.

 

send函数和recv函数的最后一个参数是收发数据时的可选项。该可选项可利用位或运算同时传递多个信息、

 

sendrecv函数的可选项及含义

MSG_OOB :用于传输带外数据 Out-of-band data  MSG_PEEK:验证输入流缓冲中是否存在接收的数据   MSG_DONTROUTE:数据传输过程中不参照路由表Routing,在本地Local网络中寻找目的地   MSG_DONTWAIT:调用I/O函数时不阻塞,用于使用非阻塞Non-blocking I/O   MSG_WAITALL:防止函数返回,直到接收全部请求的字节数  


MSG_OOB发送紧急消息

用于发送带外数据的紧急消息、用于创建特殊发送方法和通道以发送紧急消息、

fcnt1(recv_sock, F_SETOWN, gitpid());

fcnt1函数用于控制文件描述符,含义如下:“将文件描述符recv_sock指向的套接字拥有者(F_SETOWN)改为把getpid函数返回值用于ID的进程”。


注:操作系统实际创建并管理套接字,“套接字拥有者”是操作系统。此处的“拥有者”是指负责套接字所有事物的主体。

文件描述符recv_sock指向的套接字印发的SIGURG信号处理进程变为将getpid函数返回值用作ID的进程。

 

多个进程可以共同拥有1个套接字的文件描述符。


通过MSG_OOB可选项传递数据时,不会加快数据传输速度,而且通过信号处理函数读取数据只能读1个字节。MSG_OOB含义OUT-OF-DATA,"带外数据",指的是“通过完全不同的通信路径传输的数据”。

真正意义上的Out-pf-band需要单独的通信路径高速传输数据,但TCP不另外提供,只利用TCP的紧急模式进行传输。

 

紧急模式工作原理

MSG_OOB的意义在于督促数据接收对象尽快处理数据。

 

紧急消息传输阶段的输出缓冲

8

9

0

.

.

.

.

偏移量0

 

 

偏移量3

 

 

 

 

将缓冲最做到的位置视作偏移量为0,字符0保存于偏移量为2的位置。偏移量3的位置存有紧急指针UrgentPointer.紧急指针指向紧急消息的下一个位置(偏移量加1),同时向对方主机传递如下信息:紧急指针指向的偏移量为3之前的部分就是紧急消息。

实际上只有1个字节表示紧急消息。


设置URG的数据包

URG=1,URG指针=3

8

9

0

TCP头

TCP头中含有如下两个消息:

URG=1:载有紧急消息的数据包

URG指针:紧急指针位于偏移量为3的位置。

指定MSG_OBB选项的数据包本身就是紧急数据包,并通过紧接指针表示紧急消息所在位置。

 

注意:偏移量就是参照基准位置表示相对位置的量。偏移量表示距离基准点向那个方向偏移多长距离。偏移地址每次从0开始。

 

检查输入缓冲

同时设置MSG_PEEK和MSG_DONTWAIT选项,以验证输入缓冲中是否存在接收的数据。设置MSG_PEEK选项并调用recv函数时,即使读取了输入缓冲数据也不会删除。该选项通常与MSG_DONTWAIT合作,用于调用以非阻塞方式验证待读取数据存在与否的函数。

 

 

readv & writev函数

使用readv & writev函数

功能:对数据进行整合传输及发送的函数。


通过writev函数可以吧分散保存在多个缓冲中的数据一并发送,通过readv函数可以由多个缓冲分别接收。适当使用2个函数可以减少I/O函数的调用次数。

#include<sys/uio.h>  ssize_t writev(int filedes, const struct iovec *iov, int iovcnt);

成功时返回发送的字节数,失败返回-1


filedes:表示数据传输对象的套接字文件描述符。该函数并不只限于套接字,因此,可以像read函数一样向其传递文件或标准输出描述符。

iov:ioves结构体数组的地址值,结构体iovec中包含待发送数据的位置和大小信息。

iovcnt:向第二个参数传递数组长度。

struct iovec {  void * iov_base;//缓冲地址   size_t iov_len;//缓冲大小   };


下面介绍readv函数,与writev函数正好相反。
#include<sys/uio.h>  ssize_t readv(int filedes, const struct iovec *iov, int iovcnt);

成功时返回发送的字节数,失败返回-1

 

合理使用readv & writev函数

C角度看,减少函数调用次数也能相应提高性能,但其更大意义在于减少数据包个数。










原创粉丝点击