对于 UDP 套接字,发送函数不会失败,但写入的数据仍然少于请求的数据,这是否真的会发生?
Can it realistically happen that for an UDP socket, the send function doesn't fail, but still writes less data than requested?
来自man 2 sendto
:
On success, these calls return the number of bytes sent. On error, -1 is returned, and errno is set appropriately.
我是否理解未能写入所有数据不被视为这些函数的失败,因此实际上可能会发生在写入 UDP 套接字时,send()
函数写入的数据少于请求的数据, 但失败的原因未在 errno
?
中指定
或者我可以假定 send()
将 return -1
并适当地设置 errno
,或者 return 请求发送的字节数?
换句话说:这个错误处理代码是否足够:
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");
}
不存在仅发送数据报的一部分的概念。要么全部消失,要么 none 消失。 OS 或网络驱动程序不会为您拆分数据报。返回发送的字符数必须只是一种礼貌,与其他 send
API 函数保持一致。
同样来自手册页:
For sendto()
, if the message is too long to pass atomically through the underlying protocol, the error EMSGSIZE
is returned, and the message is not transmitted.
显然,@Paul Bentley 已经提供了正确的答案,但如果您担心——即使这永远不会发生——它可能会出现一些罕见的错误情况,它可能至少对于特定的实现 (Linux),net/ipv4/udp.c
中的 udp_sendmsg
的代码(这是 UDP 套接字上的 send
最终调用的代码会有所帮助) 只有一个出口可以 return 一个非负值,它 return 是调用者提供的长度:
int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
{
... code that doesn't modify len ...
out:
...
if (!err)
return len;
...
}
来自man 2 sendto
:
On success, these calls return the number of bytes sent. On error, -1 is returned, and errno is set appropriately.
我是否理解未能写入所有数据不被视为这些函数的失败,因此实际上可能会发生在写入 UDP 套接字时,send()
函数写入的数据少于请求的数据, 但失败的原因未在 errno
?
或者我可以假定 send()
将 return -1
并适当地设置 errno
,或者 return 请求发送的字节数?
换句话说:这个错误处理代码是否足够:
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");
}
不存在仅发送数据报的一部分的概念。要么全部消失,要么 none 消失。 OS 或网络驱动程序不会为您拆分数据报。返回发送的字符数必须只是一种礼貌,与其他 send
API 函数保持一致。
同样来自手册页:
For
sendto()
, if the message is too long to pass atomically through the underlying protocol, the errorEMSGSIZE
is returned, and the message is not transmitted.
显然,@Paul Bentley 已经提供了正确的答案,但如果您担心——即使这永远不会发生——它可能会出现一些罕见的错误情况,它可能至少对于特定的实现 (Linux),net/ipv4/udp.c
中的 udp_sendmsg
的代码(这是 UDP 套接字上的 send
最终调用的代码会有所帮助) 只有一个出口可以 return 一个非负值,它 return 是调用者提供的长度:
int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
{
... code that doesn't modify len ...
out:
...
if (!err)
return len;
...
}