- 浏览: 142373 次
文章分类
最新评论
recv 和 send 函数类似于标准的 read 和 wirte 函数,不过多了一个额外的参数。
这两个函数的前三个参数等同于 read 和 write 的 3 个参数,flags 参数的值或为 0,或为下表中的一个或多个常值的逻辑或。
其中各标志选项的含义如下。
* MSG_DONTROUTE:告知内核目的主机在某个直接连接的本地网络上,而无需查找路由表。这可使用本标志针对单个输出操作开启,也可使用 SO_DONTROUTE 套接字选项(见通用套接字选项)针对某个给定套接字上的所有输出操作开启。
* MSG_DONTWAIT:临时将当个 I/O 操作指定为非阻塞。
* MSG_OOB:对于 send,表示即将发送带外数据;对于 recv,表示即将读入的是带外数据。后面会讲到,TCP 连接上只有一个字节可以作为带外数据发送。
* MSG_PEEK:适用于 recv 和 recvfrom 函数,它允许我们查看已可读取的数据,而且系统不会在 recv 或 recvfrom 返回后丢弃这些数据。
* MSG_WAITALL:告知内核不要在尚未读入请求数目的字节前让一个读操作返回。当然,当(a)捕获一个信号,(b)连接被终止,(c)套接字发生错误时仍有可能返回比所请求的字节数要少的数据。
另有一些标志适用于 TCP/IP 以外的协议族,比如 OSI 的传输层是基于记录的(TCP 是基于字节流),其输出操作支持 MSG_EOR 标志,用于指示逻辑记录的结束。
最后,这两个函数的 flags 参数都是按值传递的,内核无法向进程传回标志,因此如果一个进程需要由内核更新标志,它就必须调用更为通用的 recvmsg 和 sendmsg 函数。
在 msghdr 结构的成员变量之中:
msg_name 和 msg_namelen 用于套接字未连接的场合(如未连接的 UDP 套接字),msg_name 指向一个套接字地址结构,用来存放接收者(对于 sendmsg)或发送者(对于 recvmsg)的协议地址。如果无需指明协议地址(如对于 TCP 或已连接 UDP 套接字),应将其置为空指针。msg_namelen 对于 sendmsg 是一个值参数,对于 recvmsg 则是一个值-结果参数,表示协议地址的长度。
msg_iov 和 msg_iovlen 用于指定输入或输出缓冲区数组,类似于 readv 或 writev 的第二个和第三个参数(见 readv/writev 函数及存储映射 I/O)。msg_control 和 msg_controllen 用于指定可选的辅助数据的位置和大小,这会在后面介绍。
这里还需要区分 recvmsg 和 sendmsg 的 flags 参数和 msghdr 结构的 msg_flags 成员。
1、只有 recvmsg 使用 msg_flags 成员。在调用 recvmsg 时,flags 参数会被复制到 msg_flags 成员,并由内核使用其值驱动接收处理过程。内核还依据 recvmsg 的结果更新 msg_flags 成员的值。
2、sendmsg 会忽略 msg_flags 成员,因为它直接使用 flags 参数驱动发送处理过程。这意味着如果想在某个 sendmsg 调用中设置 MSG_DONTWAIT 等标志,要设置的应该是 flags 参数,而非 msg_flags 成员。
下表汇总了内核为输入和输出函数检查的 flags 参数值以及 recvmsg 可能返回的 msg_flags 成员值。
其中,内核只检查而不返回前 4 个标志,既检查又返回接下来的 2 个标志,不检查而只返回后 4 个标志。recvmsg 返回的 7 个标志解释如下。
* MSG_BCAST:它的返回条件是本数据报作为链路层广播收取或者其目的 IP 地址是一个广播地址。它是比用 IP_RECVDSTADDR 套接字选项来判定一个 UDP 数据报是否发往某个广播地址的更好方法。
* MSG_MCAST:它的返回条件是本数据报作为链路层多播收取。
* MSG_TRUNC:它的返回条件是本数据报被截断,即内核预备返回的数据超过进程事先分配的空间(所有 iov_len 成员之和)。
* MSG_CTRUNC:它的返回条件是本数据报的辅助数据被截断,即内核预备返回的辅助数据超过进程事先分配的空间(msg_controllen)。
* MSG_EOR:它的返回条件是返回数据结束一个逻辑记录。
* MSG_OOB:它绝不为 TCP 带外数据返回,用于其他协议族(如 OSI)。
* MSG_NOTIFICATION:它由 SCTP 接收者返回,指示读入的消息是一个事件通知,而不是数据消息。
#include <sys/socket.h> ssize_t recv(int sockfd, void *buff, size_t nbytes, int flags); ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags); /* 返回值:若成功则为读入或写出的字节数,否则为 -1 */
这两个函数的前三个参数等同于 read 和 write 的 3 个参数,flags 参数的值或为 0,或为下表中的一个或多个常值的逻辑或。
其中各标志选项的含义如下。
* MSG_DONTROUTE:告知内核目的主机在某个直接连接的本地网络上,而无需查找路由表。这可使用本标志针对单个输出操作开启,也可使用 SO_DONTROUTE 套接字选项(见通用套接字选项)针对某个给定套接字上的所有输出操作开启。
* MSG_DONTWAIT:临时将当个 I/O 操作指定为非阻塞。
* MSG_OOB:对于 send,表示即将发送带外数据;对于 recv,表示即将读入的是带外数据。后面会讲到,TCP 连接上只有一个字节可以作为带外数据发送。
* MSG_PEEK:适用于 recv 和 recvfrom 函数,它允许我们查看已可读取的数据,而且系统不会在 recv 或 recvfrom 返回后丢弃这些数据。
* MSG_WAITALL:告知内核不要在尚未读入请求数目的字节前让一个读操作返回。当然,当(a)捕获一个信号,(b)连接被终止,(c)套接字发生错误时仍有可能返回比所请求的字节数要少的数据。
另有一些标志适用于 TCP/IP 以外的协议族,比如 OSI 的传输层是基于记录的(TCP 是基于字节流),其输出操作支持 MSG_EOR 标志,用于指示逻辑记录的结束。
最后,这两个函数的 flags 参数都是按值传递的,内核无法向进程传回标志,因此如果一个进程需要由内核更新标志,它就必须调用更为通用的 recvmsg 和 sendmsg 函数。
#include <sys/socket.h> ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags); ssize_t sendmsg(int sockfd, struct msghdr *msg, int flags); /* 返回值:若成功则为读入或写出的字节数,否则为 -1 */ struct msghdr{ void *msg_name; // protocol address socklen_t msg__namelen; // size of protocol address struct iovec *msg_iov; // scatter/gather array int msg_iovlen; // # elements in msg_iov void *msg_control; // ancillary data (cmsghdr struct) socklen_t msg_controllen; // length of ancillary data int msg_flags; // flags returned by recvmsg() };
在 msghdr 结构的成员变量之中:
msg_name 和 msg_namelen 用于套接字未连接的场合(如未连接的 UDP 套接字),msg_name 指向一个套接字地址结构,用来存放接收者(对于 sendmsg)或发送者(对于 recvmsg)的协议地址。如果无需指明协议地址(如对于 TCP 或已连接 UDP 套接字),应将其置为空指针。msg_namelen 对于 sendmsg 是一个值参数,对于 recvmsg 则是一个值-结果参数,表示协议地址的长度。
msg_iov 和 msg_iovlen 用于指定输入或输出缓冲区数组,类似于 readv 或 writev 的第二个和第三个参数(见 readv/writev 函数及存储映射 I/O)。msg_control 和 msg_controllen 用于指定可选的辅助数据的位置和大小,这会在后面介绍。
这里还需要区分 recvmsg 和 sendmsg 的 flags 参数和 msghdr 结构的 msg_flags 成员。
1、只有 recvmsg 使用 msg_flags 成员。在调用 recvmsg 时,flags 参数会被复制到 msg_flags 成员,并由内核使用其值驱动接收处理过程。内核还依据 recvmsg 的结果更新 msg_flags 成员的值。
2、sendmsg 会忽略 msg_flags 成员,因为它直接使用 flags 参数驱动发送处理过程。这意味着如果想在某个 sendmsg 调用中设置 MSG_DONTWAIT 等标志,要设置的应该是 flags 参数,而非 msg_flags 成员。
下表汇总了内核为输入和输出函数检查的 flags 参数值以及 recvmsg 可能返回的 msg_flags 成员值。
其中,内核只检查而不返回前 4 个标志,既检查又返回接下来的 2 个标志,不检查而只返回后 4 个标志。recvmsg 返回的 7 个标志解释如下。
* MSG_BCAST:它的返回条件是本数据报作为链路层广播收取或者其目的 IP 地址是一个广播地址。它是比用 IP_RECVDSTADDR 套接字选项来判定一个 UDP 数据报是否发往某个广播地址的更好方法。
* MSG_MCAST:它的返回条件是本数据报作为链路层多播收取。
* MSG_TRUNC:它的返回条件是本数据报被截断,即内核预备返回的数据超过进程事先分配的空间(所有 iov_len 成员之和)。
* MSG_CTRUNC:它的返回条件是本数据报的辅助数据被截断,即内核预备返回的辅助数据超过进程事先分配的空间(msg_controllen)。
* MSG_EOR:它的返回条件是返回数据结束一个逻辑记录。
* MSG_OOB:它绝不为 TCP 带外数据返回,用于其他协议族(如 OSI)。
* MSG_NOTIFICATION:它由 SCTP 接收者返回,指示读入的消息是一个事件通知,而不是数据消息。
发表评论
-
Unix 域套接字与描述符的传递
2019-03-27 23:59 716在Unix 域套接字概述一节中介绍了什么是 U ... -
Unix 域套接字概述
2019-03-12 22:48 981Unix 域协议并不是一个实际的协议族,而是在 ... -
kqueue 接口
2019-03-06 00:47 698kqueue 接口是 ... -
辅助数据
2019-02-28 00:40 693辅助数据(a ... -
inetd 守护进程介绍
2019-01-09 21:51 1061在 4.3 BSD 系统之前,很多网络服务都是 ... -
主机名与 IP 地址的转换(续)
2018-12-25 00:37 960在主机名与 IP 地址的转换一节中提到的 ge ... -
主机名与 IP 地址的转换
2018-11-14 00:20 2335在网络编程中,尽管大部分情况下操作的都是 IP ... -
SCTP 事件通知
2018-02-08 03:49 996SCTP 提供了多种可用的通知,用户可经由这些通知追踪 ... -
SCTP 套接字选项
2018-02-04 09:35 1704在获取和设置套接 ... -
SCTP 套接字编程基础函数
2018-02-04 10:08 1061SCTP 服务器可以使 ... -
SCTP 套接字编程基础概念
2018-01-18 00:10 566SCTP 套接字分为一到一套接字和一到多套接字。提供一 ... -
UDP套接字编程基础
2018-01-14 10:37 576下图显示了使用 UDP 套接字编写客户/服务器程序时的 ... -
通用套接字选项
2018-01-02 00:46 555在获取和设置套接 ... -
获取和设置套接字选项
2017-12-29 08:21 445下面几种方法可用 ... -
I/O 复用之 poll 函数
2017-12-27 00:20 428poll 函数提供的功能与 select 类似,不过在 ... -
I/O 复用之select 函数
2017-12-12 00:32 519select 函数允许进 ... -
Unix 5 种 IO 模型概述
2017-11-19 01:44 308Unix 下有 5 种可用 ... -
套接字创建、连接和关闭函数
2017-08-13 17:16 671下图是一对 TCP 客户与服务器进程之间发生的一些典型 ... -
字节转换和填充函数
2017-08-06 01:09 433网络编程中,为保证发送协议栈和接收协议栈就如 32 位 ... -
IPv4 和 IPv6 的套接字地址结构
2017-08-01 21:03 742大多数套接字函数 ...
相关推荐
Linux系统中的IO函数主要有read、write、recv、send、recvmsg、sendmsg、readv、writev,本篇主要介绍他们的使用以及区别。 read函数: #include ssize_t read(int fd,void *buf,size_t count); read...
在Linux和UNIX中有很多的输入输出函数,有时真是让想跟它攀点关系的菜鸟们束手无策。先来看看都有哪些函数,通过解析与总结,看看能不能让大家能这些函数有个理性的认识,哦,原来是这么回事,也就算我没白花这份闲...
在Unix域Socket的stream方式下,`recvmsg`和`sendmsg`函数可以实现更复杂的I/O操作,它们相比于常规的`recv`和`send`函数提供了更多的灵活性。 1. `recvmsg`函数: - `recvmsg`不仅可以接收数据,还可以获取关于...
这一层是应用程序与网络通信的接口,提供了一套标准API,如socket、bind、listen、connect、accept、send、recv等。在内核中,每个socket用`struct socket`结构体表示。相关的代码主要位于`/net/socket.c`和`/...
9.3 函数比recvmsg和sendmsg 本章小结 第十章 守护进程和超级服务器inetd 10.1 守护进程的原理 10.2 编程实践 10.3 超级服务器inetd的工作原理 10.3.1 超级服务器的概念 10.3.2 超级...
9.2.5 使用recvmsg()和sendmsg()函数 253 9.3 IO模型 256 9.3.1 阻塞IO模型 256 9.3.2 非阻塞IO模型 257 9.3.3 IO复用 257 9.3.4 信号驱动IO模型 258 9.3.5 异步IO模型 258 9.4 select()函数和pselect...
11.4 recvmsg和sendmsg函数 11.5 辅助数据 11.6 本章小结 第12章 多线程编程及网络应用 12.1 基本概念 12.1.1 引入多线程的原因 12.1.2 线程的基本概念 12.1.3 线程的分类 12.2 线程基础 12.2.1 线程的...
4. **套接字选项和控制消息**:setsockopt()和getsockopt()函数允许程序员调整套接字的行为,而recvmsg()和sendmsg()可以处理控制信息,如套接字级别的错误信息。 5. **多路复用I/O**:select()、poll()和epoll()等...
- `sendmsg` 和 `recvmsg` 函数:通用函数,支持所有其他数据传输功能。 ##### 2.3 选项管理 - **选项管理函数** - `setsockopt` 和 `getsockopt` 函数:设置或获取Socket的选项,例如多播、广播等。 - `fcntl` ...
另外,`sendmsg()`和`recvmsg()`函数允许发送和接收控制信息,如套接字地址和时间戳,这对于某些高级功能如传递文件描述符(Unix域套接字)很有用。 6. **错误处理和调试**:源码通常会包含丰富的错误处理代码,...
read、write与recv、send readline实现 用readline实现回射客户/服务器 getsockname、getpeername gethostname、gethostbyname、gethostbyaddr 11socket编程(六) TCP回射客户/服务器 TCP是个流协议 僵进程...
read、write与recv、send readline实现 用readline实现回射客户/服务器 getsockname、getpeername gethostname、gethostbyname、gethostbyaddr 11socket编程(六) TCP回射客户/服务器 TCP是个流协议 僵进程与...
read、write与recv、send readline实现 用readline实现回射客户/服务器 getsockname、getpeername gethostname、gethostbyname、gethostbyaddr 11socket编程(六) TCP回射客户/服务器 TCP是个流协议 僵进程...
read、write与recv、send readline实现 用readline实现回射客户/服务器 getsockname、getpeername gethostname、gethostbyname、gethostbyaddr 11socket编程(六) TCP回射客户/服务器 TCP是个流协议 僵进程...
read、write与recv、send readline实现 用readline实现回射客户/服务器 getsockname、getpeername gethostname、gethostbyname、gethostbyaddr 11socket编程(六) TCP回射客户/服务器 TCP是个流协议 僵进程...
5. 数据传输:通过`send`和`recv`函数进行数据发送和接收,这两个函数在TCP模式下是可靠的,保证数据的顺序和完整性。 三、UDP通信 1. UDP通信不涉及连接过程,而是直接使用`sendto`和`recvfrom`函数向特定地址和...
- `sendmsg()` 和 `recvmsg()`:这两个函数提供更高级的控制,可以发送和接收多个数据片段,适用于更复杂的TCP通信场景。 - `shutdown()`:用于关闭套接字的读写端或全部。 - `close()`:关闭一个套接字,释放...
6. **数据传输**:使用send()和recv()函数进行数据的发送和接收。 7. **关闭连接**:使用closesocket()函数关闭套接字。 8. **清理资源**:最后调用WSACleanup()函数释放Winsock资源。 ##### 4.2 具体应用实例 书中...
5. **数据传输**:`send`和`recv`函数用于发送和接收数据。TCP是面向连接的,保证数据顺序,而UDP是无连接的,不保证数据顺序或到达。 6. **错误处理**:所有WinSock函数都可能返回错误代码,开发者需要检查并适当...