send() - Unix 和 Linux 系统调用
广告
名称send、sendto、sendmsg - 在套接字上发送消息语法
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int s, const void *buf, size_t len, int flags);
ssize_t sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);
ssize_t sendmsg(int s, const struct msghdr *msg, int flags); 描述系统调用 send()、sendto() 和 sendmsg() 用于将消息传输到另一个套接字。只有当套接字处于 已连接 状态(以便知道预期的接收者)时,才能使用 send() 调用。send() 和 write() 之间的唯一区别是 flags 的存在。当 flags 参数为零时,send() 等效于 write()。此外,send(s,buf,len,flags) 等效于 sendto(s,buf,len,flags,NULL,0)。 参数 s 是发送套接字的文件描述符。 如果在连接模式(SOCK_STREAM、SOCK_SEQPACKET)套接字上使用 sendto(),则参数 to 和 tolen 将被忽略(并且当它们不为 NULL 和 0 时可能会返回错误 EISCONN),并且当套接字实际上未连接时会返回错误 ENOTCONN。否则,目标的地址由 to 给出,tolen 指定其大小。对于 sendmsg(),目标的地址由 msg.msg_name 给出,msg.msg_namelen 指定其大小。 对于 send() 和 sendto(),消息位于 buf 中,长度为 len。对于 sendmsg(),消息由数组 msg.msg_iov 的元素指向。sendmsg() 调用还允许发送辅助数据(也称为控制信息)。 如果消息太长而无法通过底层协议原子地传递,则会返回错误 EMSGSIZE,并且不会传输消息。 send() 中没有隐含的传递失败指示。本地检测到的错误由返回值 -1 指示。 当消息不适合套接字的发送缓冲区时,send() 通常会阻塞,除非套接字已置于非阻塞 I/O 模式。在这种情况下,在非阻塞模式下它将返回 EAGAIN。可以使用 select(2) 调用来确定何时可以发送更多数据。 flags 参数是以下标志的按位 OR。
标签 | 描述 |
MSG_CONFIRM(仅限 Linux 2.3+) | | 告诉链路层发生了转发进度:您从另一端获得了成功的回复。如果链路层没有收到此信息,它将定期探测邻居(例如,通过单播 ARP)。仅在 SOCK_DGRAM 和 SOCK_RAW 套接字上有效,目前仅在 IPv4 和 IPv6 上实现。有关详细信息,请参阅 arp(7)。 |
MSG_DONTROUTE | | 不要使用网关发送数据包,仅发送到直接连接网络上的主机。这通常仅由诊断或路由程序使用。这仅针对路由的协议族定义;数据包套接字没有。 |
MSG_DONTWAIT | | 启用非阻塞操作;如果操作将阻塞,则返回 EAGAIN(这也可以使用 O_NONBLOCK 与 F_SETFL fcntl(2) 启用)。 |
MSG_EOR | | 终止记录(当此概念受支持时,例如对于类型为 SOCK_SEQPACKET 的套接字)。 |
MSG_MORE(自 Linux 2.4.4 起) | | 调用者有更多数据要发送。此标志与 TCP 套接字一起使用以获得与 TCP_CORK 套接字选项相同的效果(请参阅 tcp(7)),区别在于此标志可以在每个调用基础上设置。 自 Linux 2.6 起,此标志也受 UDP 套接字支持,并通知内核将使用此标志设置的所有发送数据打包到单个数据报中,该数据报仅在执行未指定此标志的调用时传输。(另请参阅 udp(7) 中描述的 UDP_CORK 套接字选项)。 |
MSG_NOSIGNAL | | 请求在流式套接字上发生错误时不要发送 SIGPIPE,当另一端断开连接时。EPIPE 错误仍然返回。 |
MSG_OOB | | 在支持此概念的套接字(例如类型为 SOCK_STREAM 的套接字)上发送 带外 数据;底层协议也必须支持 带外 数据。 |
msghdr 结构的定义如下。有关其字段的确切描述,请参阅 recv(2) 和以下内容。
struct msghdr {
void *msg_name; /* optional address */
socklen_t msg_namelen; /* size of address */
struct iovec *msg_iov; /* scatter/gather array */
size_t msg_iovlen; /* # elements in msg_iov */
void *msg_control; /* ancillary data, see below */
socklen_t msg_controllen; /* ancillary data buffer len */
int msg_flags; /* flags on received message */
};
|
您可以使用 msg_control 和 msg_controllen 成员发送控制信息。内核可以处理的最大控制缓冲区长度受 net.core.optmem_max sysctl 限制;请参阅 socket(7)。 返回值成功时,这些调用返回发送的字符数。发生错误时,返回 -1,并且 errno 设置为适当的值。错误这些是套接字层生成的一些标准错误。其他错误可能会由底层协议模块生成和返回;请参阅它们各自的手册页。
标签 | 描述 |
EACCES | (对于由路径名标识的 Unix 域套接字)目标套接字文件上拒绝写入权限,或者路径前缀中的一个目录上拒绝搜索权限。(请参阅 path_resolution(2)。) |
EAGAIN 或 EWOULDBLOCK | | 套接字被标记为非阻塞,并且请求的操作将阻塞。 |
EBADF | 指定了无效的描述符。 |
ECONNRESET | | 连接被对等方重置。 |
EDESTADDRREQ | | 套接字不是连接模式,并且未设置对等方地址。 |
EFAULT | 为参数指定了无效的用户空间地址。 |
EINTR | 在任何数据传输之前发生了信号。 |
EINVAL | 传递了无效的参数。 |
EISCONN | | 连接模式套接字已连接,但指定了接收者。(现在要么返回此错误,要么忽略接收者规范)。 |
EMSGSIZE | | 套接字类型要求以原子方式发送消息,并且要发送的消息的大小使得这成为不可能。 |
ENOBUFS | | 网络接口的输出队列已满。这通常表示接口已停止发送,但也可能是由瞬态拥塞引起的。(通常,这不会在 Linux 中发生。当设备队列溢出时,数据包只是被静默丢弃)。 |
ENOMEM | 没有可用的内存。 |
ENOTCONN | | 套接字未连接,并且未给出目标。 |
ENOTSOCK | | 参数 s 不是套接字。 |
EOPNOTSUPP | | flags 参数中的一些位不适用于套接字类型。 |
EPIPE | 在面向连接的套接字上,本地端已关闭。在这种情况下,进程也将接收 SIGPIPE,除非设置了 MSG_NOSIGNAL。 |
符合标准4.4BSD、SVr4、POSIX.1-2001。这些函数调用出现在 4.2BSD 中。POSIX.1-2001 仅描述 MSG_OOB 和 MSG_EOR 标志。MSG_CONFIRM 标志是 Linux 扩展。 注释上面给出的原型遵循 Single Unix Specification,就像 glibc2 一样;flags 参数在 4.x BSD 中为 'int',但在 libc4 和 libc5 中为 'unsigned int';len 参数在 4.x BSD 和 libc4 中为 'int',但在 libc5 中为 'size_t';tolen 参数在 4.x BSD 和 libc4 和 libc5 中为 'int'。另请参阅 accept(2)。根据 POSIX.1-2001,msghdr 结构的 msg_controllen 字段应类型化为 socklen_t,但 glibc 当前(2.4)将其类型化为 size_t。 错误Linux 可能会返回 EPIPE 而不是 ENOTCONN。另请参阅
广告
|