0

あるマシンから別のマシンにファイルをコピーするためにTCPソケットを使用する単純なクライアントサーバーアプリケーションを作成しました。

同じマシン上のファイルのコピーは、ファイルのmd5sumの検証に成功しますが、リモートマシンへのコピーには失敗します:(

ローカルコピー

$> my_copy file.tar.gz root@127.0.0.1:/home/viswesn/file.tar.gz

$> md5sum file.tar.gz
199b341684f528012e44dbf13512c5fc

$> md5sum /home/viswesn/file.tar.gz

199b341684f528012e44dbf13512c5fc

リモートコピー

$> my_copy file.tar.gz root@blrlapx12:/home/viswesn/file.tar.gz

$> md5sum file.tar.gz

199b341684f528012e44dbf13512c5fc

$> md5sim /home/viswesn/file.tar.gz

d4cbf92a9d2ed632e429c69334c6bf7a

サーバー側のコード

int sendFile(int sock, FILE *fp, long int size) {
int rc = -1;
char dir[DIRSIZE + 1] = {'\0'};
long int nsend = 0;
int nread = DIRSIZE;
int wc = -1;
nleft = size;

while (!feof(fp)) {        
    rc = fread(dir, sizeof(char), nread, fp);        
    nsend += rc;        
    if (rc > 0) {
            printf("Sending %ld of %ld bytes\r", nsend, size);
            wc = write(sock, dir, rc);
            if (wc != rc) {
                    printf("failed to write to sock %d %s\n", sock, strerror(errno));
                    goto end;
            }
    }
    bzero(dir, rc + 1);        
}
printf("\n");
rc = 0;
end:
   if (sock) {
      close(sock);
   }
   return (rc);
}

クライアント側のコード

int getFile(int sock, char *filename, long int startOffSet, long int size) {
   char dir[DIRSIZE + 1] = {'\0'};
   int rc = -1;  
   FILE *fp = NULL;    
   int cnt = 0;
   int nread = DIRSIZE;
   long int nrecv = 0;
   int wc = 0;
   long int nleft = size;

   fp = fopen(filename, "w");
   if (fp == NULL) {
      printf("unable to open file %s %s\n", filename, strerror(errno));
   } else {
      printf("open file %s success\n", filename);
   } 

   while(nleft > 0) {
    if (nleft < nread) {
        nread = nleft;
    }        
    cnt = read(sock, dir, nread);
    if (cnt <= 0) {
       goto end;
    }
    nleft -= cnt;
    nrecv += cnt;
    dir[cnt] = '\0';
    wc = write(fp, dir, cnt);
    if (wc != cnt) {
        printf("\nFailed to write to %d", fileno(fp));
        break;
    }        
    printf("Writing %d - [Recv : %ld] / [ Total : %ld] bytes\r", cnt, nrecv, size);
   }
   if (nrecv != size) {
       printf("\nFailed to get file data %ld/%ld - diff of %ld\n", nrecv, size, size - nrecv);
       goto end;
   }
   printf("\n");
   rc = 0;
  end:
     if (fp != NULL) {
         /* close descriptor for file that was sent */
         printf("Closing file descriptor %d\n", fileno(fp));
         fclose(fp);
    }
    return (rc);
  }
4

2 に答える 2

0

クライアントの場合、ファイルをテキスト モードで開いています。

fp = fopen(filename, "w");

これにより、クライアントとサーバーが異なるエンド オブ ラインを使用する OS 上にある場合に問題が発生する可能性があります。たとえば、Unix と Windows。ファイルをバイナリモードで開いてみてください。

fp = fopen(filename, "wb");

これで問題が解決しない場合は、kdiff3 などを使用してファイルを比較し、どこに違いがあるかを確認してください。

于 2012-08-01T19:30:55.097 に答える
0

ファイルをバイナリ モードで開いてみてくださいfopen(filename, "wb");。クライアント側でも同じことを忘れないでください。

注:コードには、より厳密なエラーチェック(fopen、fread、fwrite呼び出しが失敗する可能性があります)といくつかの対称(getFileFILE *が単独で開くときにsendFileをパラメーターとして使用する理由)が必要です。

于 2012-08-01T19:31:23.850 に答える