为什么winsock
中的send()
不能保证您请求的所有字节的交付?
这是TCP,它正在阻塞套接字。
类似地,非阻塞时也会发生这种情况。你怎么能保证你把所有的东西都寄了?
我注意到recv()
做同样的。
如果没有发送所有内容,只需再次调用send
即可。如果阻塞,你可以马上做。如果是非阻塞的,您可以等待或使用套接字发现方法(如select
或I/O完成端口)。recv
也是如此。如果你没有得到你想要的,再打电话给recv
。这就是recv
和send
返回发送或接收字节数的原因之一。
传递给send
或recv
的字节数只是一个限制。它可以发送少于这个数的数据(不过,除非是非阻塞的,否则通常不会)。但它肯定能接收到更少的信号。(操作系统无法控制它接收多少数据或何时接收数据。)
TCP为您实现。但是,如果您有一个涉及应用程序级消息的应用程序协议,那么应用程序必须实现它们。这不会奇迹般地发生。TCP不会为您"将字节粘合在一起"到消息中。TCP是字节流协议,而不是消息协议。如果你想要消息,你必须实现它们。
这个行为是"by design".
可以使用外部循环,如下例所示:
int sendBuffer (SOCKET ClientSocket, const char *buf, int len, int flags)
{
int num_left = len;
int num_sent;
int err = 0;
const char *cp = buf;
while (num_left > 0)
{
num_sent = send(ClientSocket, cp, num_left, flags);
if (num_sent < 0)
{
err = SOCKET_ERROR;
break;
}
assert(num_sent <= num_left);
num_left -= num_sent;
cp += num_sent;
}
return (err == SOCKET_ERROR ? SOCKET_ERROR : len);
}
send
告诉您它能够通过返回值发送什么。循环直到send
累计发送完所有数据或返回一个错误。