huyc

导航

send(2)

SEND(2)

NAME

send, sendto, sendmsg —— 在套接上发送消息

SYNOPSIS

#include <sys/types.h>
#include <sys/socket.h>

ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);

DESCRIPTION

系统调用send,sendto,sendmsg用于给另外一个套接字传递消息。

send只能用在CONNECTED状态的套接字上,它与write的唯一区别是参数flags,flags取0时两者是等价的。类似的,下面的两个调用也是等价的:

send(sockfd, buf, len, flags);
sendto(sockfd, buf, len, flags, NULL, 0);

其中的参数sockfd乃是发送数据的套接字描述符。

如果sendto用在一个面向连接模式(SOCK_STREAM,SOCK_SEQPACKET)的套接字上,参数dest_addr和addrlen将被忽略(如果它们取值不是NULL和0,则可能返回错误EISCONN),如果套接字并没有处在CONNECTED状态则返回错误ENOTCONN。否则,目的地址由dest_addr给出,addrlen的值指定dest_addr的尺寸大小。对于sendmsg,目的地址在msg.msg_name中给出,msg.msg_namelen指定其尺寸大小。

对于send和sendto,消息放在buf中,长度为len。对于sendmsg,消息地址存放在数组msg.msg_iov的元素里面。sendmsg还允许传递辅助数据。

如果消息长度过大,以致于底层协议无法原子地发送,则不发送消息并返回错误EMSGSIZE。

send没有特定的失败提示,所有的错误都返回值-1。

当消息不能全部填入指定套接字的发送缓冲区中时,send正常阻塞,除非它被设置了非阻塞模式。非阻塞模式的它将在这种情况下调用失败并返回错误EAGAIN和EWOULDBLOCK,select调用也许能用于决定何时可以发送更多的数据。 

flags参数可以由0与下面这些标记按位或得到。

MSG_CONFIRM (Since Linux 2.3.15)
              通知链路层收到了对方的成功回应。如果链路层没有得到这个,它将定期探测邻居。此标记只对SOCK_DGRAM和SOCK_RAW类型套接字有效,并且当前只有基于IPv4和IPv6的实现。参见arp(7)以了解细节。
MSG_DONTROUTE
              不经过网关转发直接将包发送出去,只发送到直接连接的网络。此标记通常用于诊断或路由程序。它为路由协议族定义,不支持包套接字。
MSG_DONTWAIT (since Linux 2.2)
              启用非阻塞操作;如果操作会造成阻塞,则返回EAGAIN或EWOULDBLOCK(这个行为也能通过调用fcntl(sockfd, FSETFL, O_NONBLOCK)启用)。
MSG_MORE (Since Linux 2.4.4)
              调用者还要发送更多数据。此标记在TCP套接字上使用可以获得与TCP_CORK选项(参见tcp(7))一样的效果,不同的是这个标记可以为每次调用设置。
              此标记从Linux2.6开始支持UDP套接字,知会内核打包所有以此标记发送的数据到单个数据报,直到某个调用不传递此标记才发送它。(参见udp(7)中UDP_CORK选项描述)
MSG_NOSIGNAL (since Linux 2.2)
              当面向流的套接字另外一端已经中断连接,要求出错时不要发送SIGPIPE。EPIPE仍然会被返回。
MSG_OOB
              在支持此概念的套接字上发送带外数据;底层协议必须支持带外数据。
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成员发送控制信息。内核可以处理的的每个套接字最大缓冲取长度限制值在/proc/sys/net/core/optmem_max,参见socket(7)。
RETURN VALUE
成功时,返回发送的字符数。错误时,返回-1,并设置相应错误码。
ERRORS
以下列出套接层的一些标准错误。其他的错误可能由底层协议模块生成;参见相关手册页。
EACCES (Unix域套接字)
              没有套接字文件的写权限,或者没有目录前缀的浏览权限。
EAGAIN or EWOULDBLOCK
              套接字标记为非阻塞且请求导致阻塞的操作。POSIX.1-2001在这种情况下允许二者之一返回,但却没有要求两者值要相同,因此移植的程序应该检查两种可能。
EBADF  指定了非法描述符。
ECONNRESET
              连接被远程主机RESET。
EDESTADDRREQ
              套接字不是连接模式的,也没有给出远程主机的地址。
EFAULT 参数之一指定了一个无效的用户空间地址。
EINTR  在数据传输完毕之前被信号打断;参见signal(7)。
EINVAL 传递了无效参数。
EISCONN
              连接模式的套接字已经连接,但仍然指定了接收地址。(现在要么返回错误,要么忽略指定的地址)
EMSGSIZE
              套接字类型要求原子地传递消息,但是消息的长度使之不可能完成。
ENOBUFS
              网络接口的输出队列已经满了。这通常表明接口已经停止发送,但也许是暂时的拥塞导致的。(通常这不会在Linux下出现,设备溢出时包只是被简单丢弃)
ENOMEM 没有可用内存了。
ENOTCONN
              套接字没有被连接,也没有给出目标地址。
ENOTSOCK
              参数sockfd不是一个套接字。
EOPNOTSUPP
              flags参数的某些位不适合给定的套接字类型。
EPIPE  一个面向连接的套接字的本地终端被关闭。这种情况下进程将收到SIGPIPE信号,除非MSG_NOSIGNAL被设置了。
CONFORMING TO
       4.4BSD, SVr4, POSIX.1-2001.  These function calls appeared in 4.2BSD.
       POSIX.1-2001  only  describes  the  MSG_OOB  and  MSG_EOR  flags.   The
       MSG_CONFIRM flag is a Linux extension.
NOTES
上述原型遵循Single  Unix  Specification,就像glibc2做的那样;参数flags在4.x BSD是int的,但是在libc4和libc5上是unsigned int的;参数len在4.x BSD和libc4是int的,但是在libc5上是size_t;参数addrlen在4.x BSD、libc4和libc5都是int,参见accept(2)。
根据POSIX.1-2001,msghdr结构的msg_controllen域类型应该是socklen_t,但是glibc(2.4)类型是size_t。
BUGS
       Linux可能返回EPIPE以替代ENOTCONN。
EXAMPLE
       一个sendto的简单例子在getaddrinfo(3)。
SEE ALSO
       fcntl(2), getsockopt(2), recv(2), select(2), sendfile(2),  shutdown(2),
       socket(2), write(2), cmsg(3), ip(7), socket(7), tcp(7), udp(7)
COLOPHON
       This  page  is  part of release 3.23 of the Linux man-pages project.  A
       description of the project, and information about reporting  bugs,  can
       be found at http://www.kernel.org/doc/man-pages/.

posted on 2011-10-14 11:47  huyc  阅读(1135)  评论(0编辑  收藏  举报