《TCP/IP网络编程》第13章 多种I/O函数

本章所有示例代码>>github

13.1 send & recv函数

1.       Linux中的send & recv函数

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

    -sockfd:     表示与数据传输对象连接的套接字文件描述符;

    -buf:          保存待传输数据的缓冲地址值;

    -nbytes:     待传输的字节数;

    -flags:        传输数据时指定的可选项信息;

#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);// 成功时返回接收的字节数(收到EOF时返回0),失败时返回-1

    -sockfd:     表示与数据接收对象连接的套接字文件描述符;

    -buf:          保存待接收数据的缓冲地址值;

    -nbytes:     可接收的最大字节数;

    -flags:        传输数据时指定的可选项信息;

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

2.       MSG_OOB:发送紧急消息

    MSG_OOB可选项用于创建特殊发送方法和通道以发送紧急消息。

    收到MSG_OOB紧急消息时,操作系统将产生SIGURG信号,并调用注册的信号处理函数。

    注意:通过MSG_OOB可选项传递数据时不会加快数据传输速度,而且通过信号处理函数urg_handler读取数据时也只能读1个字节。剩余数据只能通过未设置MSG_OOB可选项的普通输入函数读取。

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

3.       紧急模式工作原理

    MSG_OOB的真正意义在于督促数据接收对象尽快处理数据。这是紧急模式的全部内容,而且TCP“保持传输顺序”的传输特性依然成立。

    如果将缓冲量最左端的位置视作偏移量为0,字符0保存于偏移量为2的位置。另外,字符0右侧偏移量为3的位置存有紧急指针(UrgentPointer)。紧急指针指向紧急消息的下一个位置(偏移量加1),同时向对方主机传递如下消息:

    “紧急指针指向的偏移量为3之前的部分就是紧急消息!”

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

    “偏移量就是参照基准位置表示相对位置的量。”

4.       检查输入缓冲

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

    调用recv函数时传递MSG_DONTWAIT可选项,是为了保证即使不存在待读取数据也不会进入阻塞状态。

13.2 readv & writev函数

1.       使用readv & writev函数

    readv& writev函数有助于提高数据通信效率。

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

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

    -filedes:表示数据传输对象的套接字文件描述符,不限于套接字;

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

    -iovcnt:向第二个参数传递的数组长度;

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

示例:

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

    -filedes:     传递接收数据的文件(或套接字)描述符;

    -iov:           包含数据保存位置和大小信息的iovec结构体数组的地址值;

    -iovcnt:      第二个参数中数组的长度;

2.       合理使用readv & writev函数

  • 需要传输的数据分别位于不同缓冲(数组)时,需要多次调用write函数,此时可以通过1次writev函数调用替代操作;
  • 从C语言角度考虑,减少函数调用次数可以提高性能;但更大的意义在于减少数据包个数;



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值