重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
send, sendto, sendmsg - send a message on a socket
创新互联专注为客户提供全方位的互联网综合服务,包含不限于网站设计、做网站、永济网络推广、小程序定制开发、永济网络营销、永济企业策划、永济品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;创新互联为所有大学生创业者提供永济建站搭建服务,24小时服务热线:18982081108,官方网址:www.cdcxhl.com
系统调用 send()、sendto() 和 sendmsg() 用于将消息传输到另一个套接字。
仅当套接字处于连接状态时才可以使用 send() 调用(以便知道预期的接收者, 也就是说send()仅仅用于数据流类型的数据发送 ,对于TCP,服务端和客户端都可以使用send/recv;但是对于UDP,只能是客户端使用send/recv,服务端只能使用sendto/recvfrom,因为客户端是进行了connect操作知道要发送和接受的地址)。send() 和 write(2) 之间的唯一区别是存在 flags 参数。此外,
send(sockfd, buf, len, flags);
等价于
sendto(sockfd, buf, len, flags, NULL, 0);
参数 sockfd 是发送者套接字的文件描述符。
如果在连接模式的套接字(即套接字类型为SOCK_STREAM、SOCK_SEQPACKET)上使用 sendto(),则参数 dest_addr 和 addrlen 将被忽略(当它们不是NULL和0时可能返回错误EISCONN),若套接字没有实际连接(还没有三次握手建立连接)将返回错误ENOTCONN。 否则,目标地址由 dest_addr 给出, addrlen 指定其大小。 对于 sendmsg(),目标地址由 msg.msg_name 给出, msg.msg_namelen 指定其大小。
对于 send() 和 sendto(),消息位于 buf 中,长度为 len 。 对于sendmsg(),消息存放于 msg.msg_iov 元素指向 数组数据区 (见下)中。 sendmsg() 调用还允许发送辅助数据(也称为控制信息) 。
如果消息太长而无法通过底层协议原子传递( too long to pass atomically through the underlying protocol ),则返回错误 EMSGSIZE,并且不会传输消息。
No indication of failure to deliver is implicit in a send(). Locally detected errors are indicated by a return value of -1.
当消息不适合套接字的发送缓冲区时,send() 通常会阻塞,除非套接字已置于非阻塞 I/O 模式。 在这种情况下,在非阻塞模式下它会失败并显示错误 EAGAIN 或 EWOULDBLOCK。 select(2) 调用可用于确定何时可以发送更多数据 。
上面的的描述还是很笼统的,以TCP为例,按我的理解,我认为只要发送缓冲区有空闲位置,且此时协议栈没有向网络发送数据,那么就可以写入,对于阻塞模式,直到所有数据写入到缓冲区,就会返回,否则一直阻塞,对于非阻塞模式,是有一个超时时间的,这个由 SO_SNDTIMEO 选项控制,详细见 socket(7) ,如果当前有空闲位置可以发即当前可写入,那么就写入到缓冲区,知道超时之前写入多少算多少,然后返回成功写入的字节数,如果超时时任何数据都没写出去,或者当前就是不可写入,那么返回-1 ,并设置errno为 EAGAIN 或 EWOULDBLOCK。
The flags argument is the bitwise OR of zero or more of the following flags.
sendmsg() 使用的 msghdr 结构的定义如下:
对于未连接的套接字 msg_name 指定数据报的目标地址,它指向一个包含地址的缓冲区; msg_namelen 字段应设置为地址的大小。 对于连接的套接字,这些字段应分别指定为 NULL 和 0。 这里的未连接指的是数据报协议,连接指的是数据流协议
The msg_iov and msg_iovlen fields specify scatter-gather locations, as for writev(2).
msg_iov是一个buffer数组:
使用 msg_control 和 msg_controllen 成员发送控制信息(辅助数据)。 内核可以处理的每个套接字最大控制缓冲区长度由 /proc/sys/net/core/optmem_max 中的值限制; 见 socket(7) 。 有关在各种套接字域中使用辅助数据的更多信息,请参阅 unix(7) 和 ip(7)。
msg_flags 字段被忽略。
成功时,返回成功发送的字节数,这个字节数并不一定和我们的缓冲区大小相同 。 出错时,返回 -1,并设置 errno 以指示错误。
这些是套接字层生成的一些标准错误。 底层协议模块可能会产生和返回额外的错误; 请参阅它们各自的手册页。
4.4BSD, SVr4, POSIX.1-2001. These interfaces first appeared in 4.2BSD.
POSIX.1-2001 describes only the MSG_OOB and MSG_EOR flags. POSIX.1-2008 adds a specification of MSG_NOSIGNAL. The MSG_CONFIRM flag is a Linux extension.
根据 POSIX.1-2001,msghdr 结构的 msg_controllen 字段应该是 socklen_t 类型,而 msg_iovlen 字段应该是 int 类型,但是 glibc 目前将两者都视为 size_t。
有关可用于在单个调用中传输多个数据报的 Linux 特定系统调用的信息,请参阅 sendmmsg(2)。
Linux may return EPIPE instead of ENOTCONN.
getaddrinfo(3) 中显示了使用 send() 的示例。
功能描述:
发送消息,send只可用于基于连接的套接字,send 和 write唯一的不同点是标志的存在,当标志为0时,send等同于write。sendto 和 sendmsg既可用于无连接的套接字,也可用于基于连接的套接字。除了套接字设置为非阻塞模式,调用将会阻塞直到数据被发送完。
用法:
#include sys/types.h
#include sys/socket.h
ssize_t send(int sock, const void *buf, size_t len, int flags);
ssize_t sendto(int sock, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);
ssize_t sendmsg(int sock, const struct msghdr *msg, int flags);
参数:
sock:索引将要从其发送数据的套接字。
buf:指向将要发送数据的缓冲区。
len:以上缓冲区的长度。
flags:是以下零个或者多个标志的组合体,可通过or操作连在一起
MSG_DONTROUTE:不要使用网关来发送封包,只发送到直接联网的主机。这个标志主要用于诊断或者路由程序。
MSG_DONTWAIT:操作不会被阻塞。
MSG_EOR:终止一个记录。
MSG_MORE:调用者有更多的数据需要发送。
MSG_NOSIGNAL:当另一端终止连接时,请求在基于流的错误套接字上不要发送SIGPIPE信号。
MSG_OOB:发送out-of-band数据(需要优先处理的数据),同时现行协议必须支持此种操作。
to:指向存放接收端地址的区域,可以为NULL。
tolen:以上内存区的长度,可以为0。
linuxsend返回值为9:
linuxsend返回值为9因为OS Linux Mint 14.客户端在启动时向服务器发送请求以获取一些会话参数,包括usec中的超时 . 客户端打开一个套接字并设置一个默认超时值,以便在recvfrom上不被无限制地阻塞,然后发送对这些参数的请求,关闭所述套接字,重新打开设置新超时值的套接字,最后询问用户用于命令 .
参数请求由子函数处理,该子函数除了其他之外还获得指向客户端套接字的指针,因此如果新的sockfd是不同的数字,则主函数也将能够引用新的套接字 . (返回值用作检查值,零或非零)