我正在尝试通过TCP套接字逐块发送数据。服务器代码执行以下操作:
#define CHECK(n) if((r=n) <= 0) { perror("Socket error\n"); exit(-1); }
int r;
//send the number of blocks
CHECK(write(sockfd, &(storage->length), 8)); //p->length is uint64_t
for(p=storage->first; p!=NULL; p=p->next) {
//send the size of this block
CHECK(write(sockfd, &(p->blocksize), 8)); //p->blocksize is uint64_t
//send data
CHECK(write(sockfd, &(p->data), p->blocksize));
}
在客户端,我先读取大小,然后读取数据(相同的CHECK makro):
CHECK(read(sockfd, &block_count, 8));
for(i=0; i<block_count; i++) {
uint64_t block_size;
CHECK(read(sockfd, &block_size, 8));
uint64_t read_in=0;
while(read_in < block_size) {
r = read(sockfd, data+read_in, block_size-read_in); //assume data was previously allocated as char*
read_in += r;
}
}
只要客户端和服务器都在同一台计算机上运行,此方法就可以很好地工作,但是一旦我通过网络尝试此操作,它有时就会失败。特别是,前300-400个块(约587字节)可以正常工作,但随后我得到了不正确的block_size读数:
received block #372 size : 586
read_in: 586 of 586
received block #373 size : 2526107515908
然后很显然它崩溃了。
我给人的印象是,TCP协议(protocol)可确保不会丢失任何数据,并且可以按正确的顺序接收所有内容,但是考虑到它已经在本地工作,那么这怎么可能呢?我在这里又犯了什么错误呢?
最佳答案
不能保证当您读取block_count
和block_size
时,您将一次性读取所有8个字节。