Man——send

Man——send,第1张

Man——send(2)翻译

##纯手打

Man——send(2)

-->NAME:

send, sendto, sendmsg - 在socket上发送一条消息

-->总览:

#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);

-->描述:

系统调用send(), sendto(), and sendmsg()用于传输一条消息到另一个socket。


Send()只可能在socket处于连通状态时使用(只有这样接收者才能收到消息)。


Send()和write(2)唯一的不同在于send()的flags参数。


当flags值为0时,send()相当于 write(2)。


同样,send(sockfd, buf, len, flags)等效于sendto(sockfd, buf, len, flags, NULL, 0)。


参数sockfd 是发送端socket的文件描述符。


如果sendto()用于SOCK_STREAM, SOCK_SEQPACKET连接模式的socket之上,参数dest_addr 和 addrlen 会被无视(当这两个参数非NULL或非0,调用可能会返回error EISCONN)。


如果socket没有连通则会返回error ENOTCONN。


有连通,则对端地址会以addrlen的大小赋值到dest_addr。


对于sendmsg(),则由msg.msg_name给出大小为msg.msg_namelen。


对于send()和 sendto(),要发送的消息存于buf,且长为len。


对于sendmsg(),消息参数msg.msg_iov数组指定。


Sendmsg()也可以用来发送辅助性的数据(即控制信息)。


如果消息太长以至于不能原子性地通过底层的协议,会返回error EMSGSIZE,并且消息不会被传输。


No indication of failure to deliver is implicit in a send().(??)。


返回-1表明本地调用的错误。


当消息的大小与发送缓冲不匹配时,send()一般会阻塞,除非socket的创建为nonblocking I/O模式。


对于非阻塞模式,这种情况则会失败并返回 error EAGAIN or  EWOULDBLOCK。


Select(2)调用可以决定什么是否发送更多数据。


参数flags是0或以下更多标记的按位或运算结果:

·MSG_CONFIRM (since Linux 2.3.15)

告诉连接层:你成功收到对端的响应。


如果连接层没有收到这个标记,它会不断地再次探测neighbor(??)(譬如通过ARP单播。


只在SOCK_DGRAM 和SOCK_RAW sockets可用,而且当且只在IPv4 和IPv6上实现了。


详见 arp(7) f。


· MSG_DONTROUTE

不使用网关发送包,直接通过直连的网络发送到主机。


这一般只用于诊断网络或路由的程序。


这个只为需要路由的协议族定义了。


This is defined only for protocol  families  that route; packet sockets don't.(??)

·MSG_DONTWAIT (since Linux 2.2)

允许非阻塞 *** 作,如果 *** 作是阻塞的,会返回             EAGAIN或 EWOULDBLOCK (这也可以通过F_SETFL fcntl(2)设置O_NONBLOCK实现。


·MSG_EOR (since Linux 2.2)

Terminates  a  record(??) (如果支持这个标记,对SOCK_SEQPACKET类型的sockets 有效)。


·MSG_MORE (Since Linux 2.4.4)

调用者需要发送更多数据。


这个标记配合TCP  sockets使用,取得同TCP_CORK socket 选项的效果,不同的是这个标记是单次调用生效的。


自Linux 2.6后, 这个标记也支持UDP sockets,而且会通知内核,将带有这个标记的send调用打包到一个数据报里,这些数据只有在不带这标记的send调用中才会被发送。


(See also the UDP_CORK              socket option described in udp(7).)

·MSG_NOSIGNAL (since Linux 2.2)

请求在流sockets的使用中,当对端断开连接引起错误时不发送SIGPIPE。


而仍然返回可能会EPIPE  error。


·MSG_OOB

在支持这个标记的sockets上发送带外数据。


(如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 */

size_t        msg_controllen; /* ancillary data buffer len */

int           msg_flags;      /* flags on received message */

};

你可以用 msg_control 和msg_controllen的成员发送控制信息。


对每个socket,内核可处理的最大的控制缓冲长度由socket by the value in /proc/sys/net/core/optmem_max限制。


见socket(7)。


-->返回值

成功返回成功发送的字符数。


错误则返回-1,且设置适当的errno。


-->ERRORS

一下这些是sockets层生成的标准错误。


其他错误可能会由底层 的协议模块生成和返回。


参见各自的man手册页。


·EACCES (对unix域sockets有效,由路径名区分)

对目的socket 文件没有写权限,或者对某些目录路径的前缀没有搜索权限。


(参见path_resolution(7).)

(对UDP sockets)在单播地址上作出 网络/广播地址的 *** 作。


·EAGAIN or EWOULDBLOCK

Socket被标记为nonblocking(非阻塞),而请求的 *** 作会导致阻塞。


此时,POSIX.1-2001规定允许返回这个两个错误标记,并且并不要求两个常量有相同的值,所以可移植应用应同时检查两个可能的值。


·EBADF  声明了一个无效的文件描述符

·ECONNRESET  对端重置了连接

·EDESTADDRREQ socket不是连接模式,且没有设置对端地址

·EFAULT 设置了无效客户端地址

·EINTR  在传输数据前收到信号,见signal(7).

·EINVAL  无效参数

·EISCONN 连接模式的socket 已连接,但收件人已指定。


(这种情况下,要不返回这个错误,要不忽略接收者的指定)

·EMSGSIZE  socke的类型要求消息原子性地发送,但要发送的消息的大小使这次调用无效

·ENOBUFS 网络接口的输出队列已满。


这一般说明了接口已停止已停止发送,但也可能是瞬间的阻塞造成(一般不会发生在Linux上,当设备队列溢出时Linux的行为一般是静默地弃包)。


·ENOMEM 没有可用内存

·ENOTCONN socket没有连接,且没有给定目标

·ENOTSOCK 参数sockfd 不是socket文件

·EOPNOTSUPP flags参数设置与socket类型冲突

·EPIPE 本地关闭了面向连接的socket。


此时,程序会收到SIGPIPE 除非设置MSG_NOSIGNAL

-->符合4.4BSD, SVr4, POSIX.1-2001.  这些函数出现在4.2BSD.

POSIX.1-2001 只描述了MSG_OOB 和MSG_EOR标记。


 POSIX.1-2008 添加了MSG_NOSIGNAL的声明。


MSG_CONFIRM 标记是 Linux 的扩展。


-->BUGS

Linux可能返回 EPIPE而不是 ENOTCONN.

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/587265.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-12
下一篇 2022-04-12

发表评论

登录后才能评论

评论列表(0条)

保存