0

ポートに接続された別のソケットにテキスト ファイルまたは画像ファイルを送信する簡単なソケット プログラムを作成しています。ただし、ファイルのサイズもクライアントソケットに送信して、受信するバイト数を認識したいと考えています。

また、ファイル自体の代わりに特定のバイト数を送信できるものを実装したいと考えています。たとえば、送信したいファイルが 14,003 バイトで、400 バイトを送信したい場合、400 バイトしか送信されません。

私はこのようなものを実装しています:

 #include <stdio.h>

 int main(int argc, char* argv[]) {
     FILE *fp;
     char* file = "text.txt";
     int offset = 40;
     int sendSize = 5;
     int fileSize = 0;

     if ((fp = fopen(file, "r")) == NULL) {
         printf("Error: Cannot open the file!\n");
         return 1;
     } else {
         /* Seek from offset into the file */
         //fseek(fp, 0L, SEEK_END);
         fseek(fp, offset, sendSize + offset); // seek to sendSize
         fileSize = ftell(fp); // get current file pointer
         //fseek(fp, 0, SEEK_SET); // seek back to beginning of file
     }

     printf("The size is: %d", fileSize);
 }

offsetsendSizeファイルに 40 バイトを入力し、残りのバイトを他のプログラムに送信します。

0の代わりにの出力が得られ5ます。この背後にある理由はありますか?

4

4 に答える 4

1

最後に fseek() メソッド、次に ftell() メソッドは、ファイルのサイズを取得するための適度に移植可能な方法ですが、正確であるとは限りません。改行/改行の変換を透過的に処理しないため、標準では ftell() からの戻り値が同じ位置を探す以外の目的に役立つことを実際に保証していません。

移植可能な唯一の方法は、データがなくなるまでファイルを読み取り、バイト数を保持することです。または、(非 ANSI) Unix 標準関数を使用してファイルを stat() します。

于 2016-10-14T07:50:52.287 に答える
1

オプションがなくても、Windows はファイルをテキスト モードで開くことができるため、ファイルをテキスト モードで開いている可能"t"性があります。

ftell()また、テキスト モードで開かれたファイルのサイズを取得するために使用することはできません。7.21.9.4あたりftellC 標準の機能:

テキスト ストリームの場合、そのファイル位置インジケータには未指定の情報が含まれます。この情報は、ストリームのファイル位置インジケータを呼び出し fseek時の位置に戻す関数で使用できます。このような 2 つの戻り値の差は、必ずしも、読み書きされた文字数の意味のある尺度ではありませんftell

ファイルの「サイズ」が返されたとしても、「テキスト」への変換によって、読み取られた実際のバイト数が変更される場合があります。

またfseek()、バイナリ ファイルの末尾を検出するために使用するのは移植性がなく、標準に準拠していません。7.21.9.2あたり fseek 関数:

バイナリ ストリームは、値が のfseek呼び出しを 有意にサポートする必要はありません。whenceSEEK_END

于 2016-10-14T20:21:01.090 に答える
-1

3番目のパラメーターが原因でシークが機能しないと思います:でシークしてみてください
(fp, offset, SEEK_SET);

彼は数値 sendSize+Offset を「元の」定数として使用しようとするため、以下の 3 つの定数値 (0、1、または 2) と比較され、何も比較されないため、常に 0 を返すように見えます。

http://www.cplusplus.com/reference/cstdio/fseek/

パラメーター

stream、offset、origin オフセット

の基準として使用される位置。これは、この関数の引数としてのみ使用される、 で定義された次の定数のいずれかによって指定

さ れ
ます 。

于 2016-10-14T07:35:42.337 に答える