对于 UDP 套接字,发送函数不会失败,但写入的数据仍然比请求的少吗?
Posted
技术标签:
【中文标题】对于 UDP 套接字,发送函数不会失败,但写入的数据仍然比请求的少吗?【英文标题】:Can it realistically happen that for an UDP socket, the send function doesn't fail, but still writes less data than requested? 【发布时间】:2017-09-30 10:58:30 【问题描述】:来自man 2 sendto
:
成功时,这些调用会返回发送的字节数。出错时,返回 -1,并正确设置 errno。
我是否理解写入所有数据失败不被视为这些函数的失败,因此在写入 UDP 套接字时,send()
函数写入的数据少于请求的数据实际上可能会发生,但是原因errno
中未指定此故障的原因?
或者我可以假设send()
将返回-1
并适当地设置errno
,或者返回请求发送的字节数?
换句话说:这个错误处理代码是否足够:
if(send(udp_sock_fd, buf, buflen, 0) == -1)
int err = errno;
fprintf(stderr, "Send failed:\n");
fprintf(stderr, strerror(err));
还是有必要这样写:
ssize_t bytes_send = send(udp_sock_fd, buf, buflen, 0);
if(bytes_send == -1)
int err = errno;
fprintf(stderr, "Send failed:\n");
fprintf(stderr, strerror(err));
else if(bytes_send < buflen)
fprintf(stderr, "Incomplete send for unknown reason.\n");
【问题讨论】:
好问题,我也很好奇。请打任何告诉你“试试看”的人。 试试吧。 :) @jnbbender slap ;P 更严肃的一点是,我不确定这有什么帮助,我想我不会引发这种情况,并且再多的失败尝试也无法证明这种情况不会发生。 如果数据报协议在应用程序级别被拆分,那么它就没有意义了! 【参考方案1】:显然,@Paul Bentley 已经提供了正确的答案,但如果您担心——即使这不应该发生——可能会出现一些罕见的错误情况,它可能会有所帮助请注意,至少对于特定的实现(Linux),net/ipv4/udp.c
中的udp_sendmsg
的代码(这是 UDP 套接字上 send
的最终调用)只有一个可以返回非负数的出口值,并返回调用者提供的长度:
int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
... code that doesn't modify len ...
out:
...
if (!err)
return len;
...
【讨论】:
【参考方案2】:没有只发送数据报的一部分的概念。要么全部进行,要么都不进行。操作系统或网络驱动程序不会为您拆分数据报。返回发送的字符数必须是出于礼貌,以便与其他 send
API 函数保持一致。
也来自手册页:
对于
sendto()
,如果消息太长,无法通过底层协议原子传递,则返回错误EMSGSIZE
,消息不传输。
【讨论】:
以上是关于对于 UDP 套接字,发送函数不会失败,但写入的数据仍然比请求的少吗?的主要内容,如果未能解决你的问题,请参考以下文章