send() - Unix,Linux系统调用
Tutorials Point


  Unix入门
  Unix Shell编程
  高级Unix
  Unix有用参考
  Unix有用资源
  精选阅读

版权所有 © 2014 tutorialspoint



  首页     参考资料     讨论论坛     关于TP  

send() - Unix,Linux系统调用


previous next AddThis Social Bookmark Button

广告

名称

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(),则参数totolen将被忽略(当它们不为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_DGRAMSOCK_RAW套接字上有效,目前仅针对IPv4和IPv6实现。有关详细信息,请参阅arp(7)。
MSG_DONTROUTE
 不要使用网关发送数据包,只发送到直接连接的网络上的主机。这通常仅由诊断或路由程序使用。这仅针对路由的协议族定义;数据包套接字没有。
MSG_DONTWAIT
 启用非阻塞操作;如果操作会阻塞,则返回EAGAIN(这也可以使用O_NONBLOCKF_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_controlmsg_controllen成员发送控制信息。内核可以处理的最大控制缓冲区长度受net.core.optmem_max sysctl每个套接字限制;参见socket(7)。

返回值

成功时,这些调用返回发送的字符数。出错时,返回-1,并适当地设置errno

错误

这些是由套接字层生成的某些标准错误。其他错误可能会由底层协议模块生成并返回;请参阅它们各自的手册页。
标签描述
EACCES (对于由路径名标识的Unix域套接字)目标套接字文件上的写权限被拒绝,或者路径前缀之一的目录上的搜索权限被拒绝。(参见path_resolution(2)。)
EAGAINEWOULDBLOCK
 套接字被标记为非阻塞,并且请求的操作将阻塞。
EBADF 指定了无效的描述符。
ECONNRESET
 连接被对端重置。
EDESTADDRREQ
 套接字不是连接模式,并且未设置对等地址。
EFAULT 为参数指定了无效的用户空间地址。
EINTR 在任何数据传输之前发生信号。
EINVAL 传递了无效的参数。
EISCONN
 连接模式套接字已连接,但指定了接收者。(现在要么返回此错误,要么忽略接收者规范。)
EMSGSIZE
 套接字类型要求原子发送消息,并且要发送的消息大小使得这成为不可能。
ENOBUFS
 网络接口的输出队列已满。这通常表示接口已停止发送,但也可能是由瞬态拥塞引起的。(通常,这不会在Linux中发生。当设备队列溢出时,数据包只是被静默丢弃。)
ENOMEM 没有可用内存。
ENOTCONN
 套接字未连接,并且未给出目标。
ENOTSOCK
 参数s不是套接字。
EOPNOTSUPP
 flags参数中的某些位不适合套接字类型。
EPIPE 在面向连接的套接字上,本地端已关闭。在这种情况下,除非设置了MSG_NOSIGNAL,否则进程也将接收SIGPIPE

符合标准

4.4BSD、SVr4、POSIX.1-2001。这些函数调用出现在4.2BSD中。

POSIX.1-2001仅描述MSG_OOBMSG_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。

参见



previous next Printer Friendly

广告


  

广告



广告