我不知道如何描述我的问题,所以我举一个例子。
Bill通过TCP scoket向Alice发送数据。以下代码是:
write(socketfd,buff,10000);
Alice已经知道数据大小总是10000.下面的代码是:
read(socketfd,buff,10000);
问题是,Alice可能获得小于10000的数据,并且她需要再次读取套接字。
答案 0 :(得分:2)
是的! TCP套接字提供了一个流接口,很有可能数据以多个部分传递。
接收器应继续读取,直到收到所有数据。
while (totalRead < expectedSize) {
result = read(socketfd,buff + totalRead, expectedSize-totalRead);
if (result < 0) {
// nothing read, check for errors
} else {
totalRead += result;
if (result == 0) {
// Other end shutdown before sending the expected amount of data
}
}
}
写作也是如此:
while (written < totalSize) {
result = write(socketfd,buff + written, totalSize - written);
if (result < 0) {
// nothing written, check for errors
} else {
written += result;
}
}
答案 1 :(得分:1)
问题是Alice是否有可能获得小于10000的数据,她需要再次读取套接字。
是
答案 2 :(得分:1)
是的,TCP不是面向数据包的,网络堆栈可能决定以任何&#34;块大小&#34;来传递传入数据。
您可能获得前10%,然后还有几秒钟的网络延迟,然后TCP可能会提供它到目前为止所获得的数据。
对于任何非明确面向数据包的I / O,您应该始终循环读取,直到您获得预期的总量。对于从普通本地文件读取也是如此。
答案 3 :(得分:1)
如果有错误怎么办?如果您需要检查已关闭的连接怎么办? read
使用返回值报告这两者。
请记住,首先TCP是没有固定数据包大小的流式协议,因此如果尚未收到所有数据,则单个呼叫可能无法读取所有数据。其次要记住,底层协议可能没有那么大的数据包用于传输,并且会将数据分成更小的块,一次只能收到一个。
是的,始终检查read
来电已阅读的实际尺寸。
答案 4 :(得分:1)
是的,写作也一样。你必须检查写入的ret值。
答案 5 :(得分:1)
读取通常会在读取一些数据后立即返回。它返回读取的实际字节数,以及错误的负数。
另一方面,TCP不能保证数据一次全部到来。因此,您应该反复检查返回代码,直到您完成读取t8ge所需的数据长度。