6

CのTCPソケットを介して画像ファイルを送信しようとしていますが、サーバー側で画像が正しく再構築されていません。誰かが間違いを指摘できるかどうか疑問に思いましたか?

サーバーが正しいファイルサイズを受信して​​いて、そのサイズのファイルを作成していることはわかっていますが、それはイメージファイルではありません。

クライアント

//Get Picture Size
printf("Getting Picture Size\n");
FILE *picture;
picture = fopen(argv[1], "r");
int size;
fseek(picture, 0, SEEK_END);
size = ftell(picture);

//Send Picture Size
printf("Sending Picture Size\n");
write(sock, &size, sizeof(size));

//Send Picture as Byte Array
printf("Sending Picture as Byte Array\n");
char send_buffer[size];
while(!feof(picture)) {
    fread(send_buffer, 1, sizeof(send_buffer), picture);
    write(sock, send_buffer, sizeof(send_buffer));
    bzero(send_buffer, sizeof(send_buffer));
}

サーバ

//Read Picture Size
printf("Reading Picture Size\n");
int size;
read(new_sock, &size, sizeof(int));

//Read Picture Byte Array
printf("Reading Picture Byte Array\n");
char p_array[size];
read(new_sock, p_array, size);

//Convert it Back into Picture
printf("Converting Byte Array to Picture\n");
FILE *image;
image = fopen("c1.png", "w");
fwrite(p_array, 1, sizeof(p_array), image);
fclose(image);

編集:サーバーコードのsizeof(int)を修正しました。

4

3 に答える 3

7

読む前にファイルの先頭を探す必要があります

fseek(picture, 0, SEEK_END);
size = ftell(picture);
fseek(picture, 0, SEEK_SET);

またはfstat、ファイルサイズを取得するために使用します。

于 2012-10-27T05:09:06.890 に答える
0

チェックfreadfwrite構文:

size_t fread(void *ptr, size_t size, size_t n, FILE *fp);

size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp);

あなたの場合、正しいステートメントは次のようになります。

fread(send_buffer, sizeof(send_buffer), 1, picture);

fwrite(p_array, sizeof(p_array), 1,image);

于 2018-03-29T08:17:46.403 に答える
0

これは古い投稿ですが、元のコードのいくつかの問題を強調する必要があります。

  • feof(picture)は、fopenの後は常にfalseです。feofを呼び出す前に必ず読んでください
  • read(new_sock、p_array、size)は、サイズバイトの読み取りが保証されていません。サイズ、ネットワーク負荷、サーバー負荷などの値によって異なります。

正しい(少なくともより堅牢な)バージョンは次のようになります:

//Send Picture as Byte Array (without need of a buffer as large as the image file)
printf("Sending Picture as Byte Array\n");
char send_buffer[BUFSIZE]; // no link between BUFSIZE and the file size
int nb = fread(send_buffer, 1, sizeof(send_buffer), picture);
while(!feof(picture)) {
    write(sock, send_buffer, nb);
    nb = fread(send_buffer, 1, sizeof(send_buffer), picture);
    // no need to bzero
}

サーバー側でも同じ問題:

//Read Picture Byte Array
printf("Reading Picture Byte Array\n");
char p_array[size];
char* current = p_array;
int nb = read(new_sock, current, size);
while (nb >= 0) {
    current = current + nb;
    nb = read(new_sock, current, size);
}

サーバー側では、大きな画像ファイルと同じくらい大きなバッファの作成を回避できます(これは大きな画像で問題になる可能性があります):

//Read Picture Byte Array and Copy in file
printf("Reading Picture Byte Array\n");
char p_array[BUFSIZE];
FILE *image = fopen("c1.png", "w");
int nb = read(new_sock, p_array, BUFSIZE);
while (nb > 0) {
    fwrite(p_array, 1, nb, image);
    nb = read(new_sock, p_array, BUFSIZE);
}
fclose(image);
于 2018-12-10T17:06:46.790 に答える