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 マクロ):
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 プロトコルは、データが失われず、すべてが正しい順序で受信されることを保証するという印象を受けましたが、ローカルで既に動作していることを考えると、これはどのように可能であり、ここでの私の間違いは何ですか?