以下のコードに問題があります。サーバーからファイルを受信するように設計されています。送信後にサーバーが切断される限り、100% 正常に動作します。
サーバーが切断されない場合、転送はクライアント側で完了せず、クライアントは引き続きバイトを待機し、ループから適切に抜け出せません (fr_block_sz == 0 の場合)。ファイルを受信した後、切断します。それは無限にループに座っています。
ファイルを受信し、その後接続を開いたままにできるようにしたいと思います。何かアドバイス?ありがとう。
編集:ケーシーのアドバイスに従って、以下のコメント付きコードを介して書き込まれたバイト数を監視していますが、ファイル転送が正しく完了しない原因となる奇妙な動作が発生しています。誰かが私のコードで何か間違ったことを見ることができますか? ありがとう。
編集 2: 問題を明確にするために、問題に関するデバッグ情報を投稿しました。
// Reciever of file (client)
int TotalSize = 7374; // hardcoded file size to expect
int FileSize = 0; // counter
int fr_block_sz = 0;
while ((fr_block_sz = recv(sd, revbuf, 1, 0)) > 0) //LENGTH == 512
{
if (fr_block_sz < 0)
if (errno == EAGAIN)
continue;
else
printf("File write failed");
if (fr_block_sz == 0)
break; //done
// edit based on comment - does not change behavior
if(FilzeSize > TotalSize)
{
fr_block_sz = fr_block_sz - (FileSize - TotalSize);
}
int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
// add total bytes recvd every loop
FileSize += write_sz;
// if bytes recieved equals expect file size, break
if (FileSize >= TotalSize)// this is where my problem is, as sometimes
// FileSize == 7376 or 7672 instead of 7374
// When it fails, fr_block_sz == 24 which
// i don't think is right either. Even when
// set to break if FileSize > TotalSize, the
// loop still doesn't complete
break;
printf("Recieved size == %i of %i \n", FilzeSize, TotalSize);
if (write_sz < fr_block_sz)
{
printf("File write failed");
}
bzero(revbuf, 1);
}
printf("Transfer complete \n");
コンソール出力:
Recieved size == 512 of 7374
Recieved size == 1024 of 7374
Recieved size == 1368 of 7374
Recieved size == 1880 of 7374
Recieved size == 2392 of 7374
Recieved size == 2736 of 7374
Recieved size == 3248 of 7374
Recieved size == 3760 of 7374
Recieved size == 4104 of 7374
Recieved size == 4616 of 7374
Recieved size == 5128 of 7374
Recieved size == 5472 of 7374
Recieved size == 5984 of 7374
Recieved size == 6496 of 7374
Recieved size == 6840 of 7374
Recieved size == 7352 of 7374
Recieved size == 7376 of 7374
ここに到達すると、クライアントはループ内で永遠に待機し、何も起こりません。次に、コンソールからプログラムを手動で停止する必要があり、プログラムが停止した後、4096 バイトのファイルしか書き込まれませんでした。誰かが私の問題、またはこれを行う「通常の」方法に光を当てることができれば、私は最も感謝しています。ありがとうございました。
編集 - 修正済み(一種)。毎回確実に 100% 動作させる方法を見つけました。それは、LENGTH == 1 を変更して、1 バイトのバッファー サイズを設定することです。カーネルがバイトごとに書き込みを行っている場合、短い/長い読み取りを取得できません。 . これは機能しますが、明らかに最速のソリューションではありません。ラジャルの助けに感謝します。