ソケットを介してファイル転送、より少ないバイトの最終的なサイズ
-
22-08-2019 - |
質問
私はC言語でソケットを通じて、いくつかのファイルを受信しようとしている。しかし、サーバは、例えば私の1000000バイトのファイルのための64バイトのパケットを送信し、私は先のファイルに約999902バイトを取得します。
while ((n = read(sd, buffer_in, BUFSIZE ))) // BUFSIZE = 64
{
if(n<0)
{
printf("Fail.\n");
fclose(archivo);
return -1;
}
if(fwrite(buffer_in, n, 1, f) !=1 )
{
printf("fwrite error.\n");
fclose(archivo);
return -1;
}
bytes+=n;
}
printf("We received %d bytes", bytes);
はなく、低速接続では、それが動作するローカルTCP / IPソケットを介して使用する場合。私は、64のバイトのチャンクの多くは、とEOFの近くに30バイトのチャンクを取得し、デバッグを見通します。私は、任意のデータ(> 1バイト)が利用可能であるときに、呼び出しが戻るので、読み取り()にはあまりバイトを得ることができることを知っています。しかし、この状態はしばらくによってcatchedすべきではありませんか?場合N == 0を返す必要があり、それにはより多くのデータ(EOF)ではない。
あなたの助けのためのThxを。
(EDIT)
次のようにコードを送信
while (n=read(file_fd, buffer, BUFSIZE))
{
write (sdaccept, buffer, n)
}
私は両方の読み取り(ことを知っている)と(書き込み)BUFSIZE (EDIT II) 10673バイトとC源でテスト、宛先ファイルが最初の98のバイトを欠いていることを除いて、破損することなく、10575を受信!!!
解決
提供送信コードは、ソケットへの書き込み()(または送信は、())バッファ全体を記述する義務はないという事実を無視します。
書き込みは、()/(送信)(例えばネットワーク・サブシステムは、データを送信するためのキューを持つことができ、このキューがすでにある根本的なサブシステムは、より多くのデータを受け取ることを拒否した場合、それは部分的またはまったく書くことにしたかもしれませんフル)。これは低速接続の可能性が高いです。
送信側は、実際に書き込まれたデータの量を検出し、それに応じて調整するように書き込み()の戻り値を確認する必要があります。
書き込みは次のように何らかの形で行われる必要があります:
int readAmount;
while( readAmount = read(file_fd, buffer, BUFSIZE) > 0 )
{
int totalWritten = 0;
do {
int actualWritten;
actualWritten = write (sdaccept, buffer + totalWritten, readAmount - totalWritten);
if( actualWritten == - 1 ) {
//some error occured - quit;
}
totalWritten += actualWritten;
} while( totalWritten < readAmount );
}