简体   繁体   中英

md5sum fails on recived file from socket

I wrote simple client - server application using TCP socket to copy file from one machine to other machine.

Copying files on same machine succeed on verifying the md5sum of the files but same fails on copying to remote machine :(

Local copy

$>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

Remote copy

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

$>md5sum file.tar.gz

199b341684f528012e44dbf13512c5fc

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

d4cbf92a9d2ed632e429c69334c6bf7a

Code on Server side

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);
}

Code on Client Side

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);
  }

For client you are opening file in text mode.

fp = fopen(filename, "w");

This could lead to issues if client and server are on OS that uses different end of line. For example Unix and Windows. Try to open file in binary mode.

fp = fopen(filename, "wb");

If this doesn't help then compare files using for example kdiff3 and check where are a differences.

Try to open file in binary mode fopen(filename, "wb"); and don't forget do the same in on the client side.

Note: your code is require more strict error checking (fopen, fread, fwrite calls can fail) and some symmetric (why sendFile use FILE * as parameter when getFile open it by itself).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM