1

作成した単純なサーバーアプリケーションとクライアントアプリケーションの間でファイルを転送しようとすると、問題が発生します。ファイルは正常に転送されますが、受信側(サーバー側)でファイルサイズが異なります。クライアント側でファイルを開き、fseek()を使用してファイルのサイズを見つけます。次に、fread()を使用してchar型のバッファーに読み込みます。UDPソケットを使用する必要があるため、sendto()を使用してこのバッファーを送信します。サーバー側では、recvfrom()を使用してこれを格納し、fwrite()を使用して別のファイルに書き込みます。しかし、ファイルのサイズを確認すると、はるかに大きくなっています。また、テキストファイルであるはずなのに開けません。私がどこで間違っているのかについて、いくつかの指針を教えていただけますか?また、これはソケットを介してファイルを送信するための最良の方法ですか?ファイルを送信するためのより良い方法はありますか?

ありがとう

クライアント側のコード

//Writing code to open file and copy it into buffer
        fseek(fp, 0, SEEK_END);
        size_t file_size = ftell(fp);
        fseek(fp, 0, SEEK_SET);
        if(fread(file_buffer, file_size, 1, fp)<=0)
        {
            printf("Unable to copy file into buffer! \n");
            exit(1);
        }

        //Sending file buffer
        if(sendto(sock, file_buffer, strlen(file_buffer), 0, (struct sockaddr *) &serv_addr, serv_len)<0)
        {
            printf("Error sending the file! \n");
            exit(1);
        }
        bzero(file_buffer, sizeof(file_buffer));

ファイルを受信するためのサーバー側のコード

//Receiving file from client
        char file_buffer[BUFSIZE];
        if(recvfrom(sock, file_buffer, BUFSIZE, 0, (struct sockaddr *) &client_addr, &client_addr_size)<0)
        {
            printf("Error receiving file.");
            exit(1);
        }

        char new_file_name[] = "copied_";
        strcat(new_file_name,file_name);
        FILE *fp;
        fp = fopen(new_file_name,"w+");
        if(fwrite(file_buffer, 1, sizeof(file_buffer), fp)<0)
        {
            printf("Error writing file! \n");
            exit(1);
        }
4

1 に答える 1

1

コードにはいくつかの問題があります。

送信者:

  • どのように割り当てfile_bufferますか?ファイルがバッファよりも大きい場合はどうなりますか?(おそらく、これは目前の問題を引き起こしていません。)

  • からの戻り値がであるかどうかを確認するだけfreadです<= 0。実際、エラーまたはEOFが発生した場合、戻り値はファイルのフルサイズよりも小さい値にすることができます。(おそらく、これは目前の問題を引き起こしていません。)

  • システムコールのstrlen(file_buffer)代わりにfile_sizeパスします。ファイルに含まれる場合と含まれない場合があるNULバイトを検索します。テキストファイルだと言うので、おそらく何も含まれていません。sendtostrlen

    • ファイルに少なくとも1つのNULバイトが含まれている場合、パケットは最初のNULバイトの前に切り捨てられ、ファイルの内容全体を送信することはありません。
    • ファイルにNULバイトが含まれていない場合、strlenバッファに読み込まれるときにファイルの終わりを超えてスキャンします。未割り当てのメモリアドレスにスキャンするためにプログラムがクラッシュするかstrlen、ファイルの終わりを超えて追加のガベージを送信します。

受信機で:

  • recvfrom受信したパケットのペイロードの長さである戻り値は無視してください。その後、受信したデータの量を知る方法はありません。

  • 結果として、受信した実際のデータ量ではなく、サイズとしてfwrite渡します。sizeof(file_buffer)これは固定値(BUFSIZE)であり、おそらくファイルよりも大きくなります。ディスクに書き込まれたファイルには、ファイルの終わりを超えてゴミが含まれます。

于 2012-10-01T13:52:20.903 に答える