sendmsg ()-在套接字上发送消息

标准

标准/扩展 C 或 C++ 依赖关系
XPG4.2 单一 UNIX 规范版本 3
两个  

格式

X/Open:
#define _XOPEN_SOURCE_EXTENDED 1
#include <sys/socket.h>

ssize_t sendmsg(int socket, struct msghdr *msg, int flags);
Berkeley 套接字:
#define _OE_SOCKETS
#include <sys/socket.h>

int sendmsg(int socket, struct msghdr *msg, int flags);

一般描述

sendmsg () 函数使用在消息头数组中传递的套接字描述符在套接字上发送消息。
PARAMETER
描述
套接字
套接字描述符。
msg
从中发送消息的消息头的数组。
flags
指定以下一个或多个标志。 如果指定了多个标志,那么逻辑 OR 运算符 (|) 必须用于分隔它们。
MSG_OOB
在套接字上发送频带外数据。 只有 SOCK_STREAM 套接字支持频带外数据。 频带外数据是单个字节。

在两个程序之间可以发送频带外数据之前,必须进行一些工作协调。 如果要不直接插入读取数据,那么频带外数据的接收方必须指定发送频带外数据时生成的 SIGURG 信号的接收方。 如果未设置收件人,那么不会发送任何信号。 通过将 fcntl () 函数的 action 参数设置为 F_SETOWN 并指定 PID 或 GID 来设置收件人。 有关为频带外数据设置收件人的更多信息,请参阅 fcntl ()-Control open file descriptors

数据的接收方通过使用 setsockopt () 函数设置 SO_OOBINLINE 套接字选项来确定是否内联接收频带外数据。 有关接收带外数据的更多信息,请参阅 setsockopt() — 设置与套接字相关的选项recv() — 在套接字上接收数据recvfrom() — 在套接字上接收消息recvmsg() — 在套接字上接收消息并存储在消息头数组中

消息 (MSG_DONTROUTE)
SO_DONTROUTE 套接字选项在操作期间开启。 此标志通常由诊断或路由程序使用。
消息头由 msghdr 结构定义,可在 sys/socket.h 头文件中找到此结构,并包含以下元素:
元素
描述
消息
包含消息的 iovec 缓冲区的数组。
msg_iovlen
msg_iov 数组中的元素数。
消息名
一个可选指针,指向包含收件人地址的缓冲区。
msg_namelen
地址缓冲区的大小。
caddr_t msg_accrights
发送或接收的访问权 (如果由用户指定,那么将忽略)。 z/OS® UNIX 服务将忽略此字段。
int msg_accrightslen
访问权数据的长度 (如果由用户指定,那么将忽略)。 z/OS UNIX 服务将忽略此字段。
msg_control
辅助数据。
msg_controllen
辅助数据缓冲区长度。
消息标志
接收到的消息上的标志。

辅助数据由一系列对组成,每个对由 cmsghdr 结构后跟一个数据数组组成。 数据数组包含辅助数据消息,而 cmsghdr 结构包含允许应用程序正确解析数据的描述性信息。

sys/socket.h 头文件定义至少包含以下元素的 cmsghdr 结构:
元素
描述
cmsg_len
数据字节计数,包括头。
cmsg_level
发端协议。
cmsg_type
特定于协议的类型。
以下辅助数据在 IPv4 级别可用:
辅助数据
描述
IP_PKTINFO
(RAW 和 UDP) 指定要发送的接口包以及用作包源 IP 的 IP 地址。 数据通过 netinet/in.h 中定义的 in_pktinfo 结构传递。
以下辅助数据在 IPv6 级别可用:
辅助数据
描述
IPV6_HOPLIMIT
(RAW , TCP 和 UDP) 指定出局包的最大中继段限制。 数据以 netinet/in.h 中定义的结构传递。
IPV6_PATHMTU
(RAW 和 UDP) 指定已连接套接字的目标的路径 MTU 值。 数据以 netinet/in.h 中定义的结构传递。
IPV6_PKTINFO
(RAW 和 UDP) 指定要发送的接口包以及用作包源 IP 的 IP 地址。 数据以 netinet/in.h 中定义的 in6_pktinfo 结构传递。
在套接字级别提供了以下辅助数据:
辅助数据
描述
SCM_权利
指定包含要发送或接收的访问权的数据数组。 此辅助数据仅对 AF_UNIX 域有效。 数据以 sys/socket.h 中定义的结构传递。
sys/socket.h 头文件定义以下宏以获取与消息头关联的辅助数据中的数据数组的访问权:
CMSG_DATA(cmsg)
如果自变量是指向 cmsghdr 结构的指针,那么此宏将返回指向与 cmsghdr 结构关联的数据数组的无符号字符指针。
CMSG_NXTHDR(mhdr 和 cmsg)
如果第一个参数是指向 msghdr 结构的指针,而第二个参数是指向辅助数据中 cmsghdr 结构的指针(由 msghdr 结构的 msg_control 字段指向),则此宏返回指向下一个 cmsghdr 结构的指针,如果此结构是辅助数据中的最后一个 cmsghdr 结构,则返回 NULL 指针。
CMSG_FIRSTHDR(mhdr)
如果自变量是指向 msghdr 结构的指针,那么此宏将返回指向与此 msghdr 结构关联的辅助数据中的第一个 cmsghdr 结构的指针,如果没有与该 msghdr 结构关联的辅助数据,那么返回 NULL 指针。

sendmsg () 调用适用于套接字,无论它们是否处于已连接状态。

此调用返回发送的数据的长度。 如果没有足够的可用缓冲区空间来保存要传输的套接字数据,并且套接字处于分块方式,那么 sendmsg () 将阻塞调用者,直到其他缓冲区空间变为可用为止。 如果套接字处于非阻塞模式,则 sendmsg() 返回 -1 并将错误代码设置为 EWOULDBLOCK。 请参阅 fcntl ()-Control open file descriptorsioctl ()-Control device ,以获取有关如何设置非分块方式的描述。

对于数据报套接字,此调用将发送整个数据报,前提是该数据报适合 TCP/IP 缓冲区。 流套接字类似于无边界分隔数据的信息流。 例如,如果应用程序希望发送 1000 字节,那么对此函数的每个调用都可以发送 1 字节, 10 字节或整个 1000 字节。 因此,使用流套接字的应用程序应该将此调用置于循环中,调用此函数,直到发送了所有数据为止。

IPv6: 对于 AF_INET6 套接字,如果指定了 msg_name ,那么该地址应该位于 sockaddr_in6 地址结构中。 sockaddr_in6 结构在头文件 netinet/in.h中定义。

C++的特殊行为: 要将此函数与 C++配合使用,必须使用 _XOPEN_SOURCE_EXTENDED 1 功能测试宏。

注: sendmsg () 函数依赖于增强型 ASCII 扩展的级别。 有关详细信息,请参阅 增强型 ASCII 支持

返回值

如果成功, sendmsg () 将返回消息的长度 (以字节为单位)。

值 0 或更大的值指示已发送的字节数,但是,这无法确保数据传递已完成。 如果数据传递未完成,那么可以通过对等套接字和稍后生成的 SIGPIPE 信号来断开连接。

如果不成功,sendmsg() 返回 -1 ,并将 errno 设置为以下值之一:
错误代码
描述
EADDRNOTAVAIL
ipi6_addr 不可用于 ipi6_ifindex 接口。
Eafnosupport
地址系列不受支持 (它不是 AF_UNIX , AF_INET 或 AF_INET6)。
EBADF
socket 不是有效的套接字描述符。
ECONNREFUSED
已拒绝尝试连接。
ECONNRESET
同级强制关闭了连接。
EfaulT
使用 msg 将导致尝试访问调用者地址空间外部的存储器。
Ehostun联系
ifi6_index指定的接口上不存在到目标的路由。
EINTR
在传输任何数据之前,信号中断了 sendmsg ()。
EINVAL
msg_namel定为 不是指定地址系列的有效地址大小。
EIO
发生了网络或传输故障。
EMSGSIZE
消息太大,无法作为单个数据报发送。 缺省值为 large-包络-size。 (包络用于在 TCP/IP 处理期间保存数据报和片段。 当处理 UDP 数据报以进行输出时,以及当它们等待应用程序在输入时接收这些 UDP 数据报时,大包络会保留大于 2KB 的 UDP 数据报。)
ENETDOWN
未启用由 ipi6_ifindex 指定的接口以供 IPv6 使用。
ENOBUFS
缓冲区空间不可用于发送消息。
ENOTCONN
未连接套接字。
ENOTSOCK
描述符用于文件,而不是用于套接字。
ENXIO
ipi6_ifindex 指定的接口不存在。
EOPNOTSUPP
socket 自变量与不支持 flags中设置的一个或多个值的套接字相关联。
EPIPE
对于已连接的流套接字,与对等套接字的连接已丢失。 向呼叫进程发送 SIGPIPE 信号。
EWOULDBLOCK
套接字 处于非分块方式,并且没有可用的数据缓冲区,或者在缓冲区变为可用之前达到 SO_SNDTIMEO 超时值。
以下仅适用于 AF_UNIX:
错误代码
描述
EACCES
拒绝对路径前缀的组件的搜索许可权,或者拒绝对指定套接字的写访问权。
EIO
读取或写入文件系统时发生 I/O 错误。
ELOOP
在转换套接字地址中的路径名时迂到过多的符号链接。
ENAMETOOLONG
路径名的组件超过了 NAME_MAX 个字符,或者整个路径名超过了 PATH_MAX 个字符。
ENOENT
路径名的组件未命名现有文件,或者路径名为空字符串。
ENOTDIR
套接字地址中路径名的路径前缀的组件不是目录。

相关信息