2011-05-24 67 views
2

我必須在C中編寫一個連接到服務器的SSL客戶端,並獲取一個html或一個文件。我設法得到的HTML,但我不能下載二進制文件。例如,我試圖從https://www.openssl.org/source/openssl-1.0.0d.tar.gz下載一個3.8MB的文件,我的代碼只設法下載1.1mb的文件,我甚至不知道我是否能夠在其中獲得正確的數據。通過C中的SSL下載文件C

這裏是我爲它所做的功能:

char *sslReadfile (connection *c) 
{ 
    const int readSize = 1024; 
    char *rc = NULL; 
    int received, count = 0; 
    char buffer[1024]; 
    char filename[40]; 
    printf("Input the file name to be saved:\n"); 
    scanf("%s",filename); 
    FILE *fp; 
    fp = fopen(filename, "wb"); 

    if (c) 
    { 
     while (1) 
     { 
      if (!rc) 
      rc = malloc (readSize * sizeof (char) + 1); 
      else 
      rc = realloc (rc, readSize * sizeof (char) + 1); 

      received = SSL_read (c->sslHandle, buffer, readSize); 
      buffer[received] = '\0'; 

      if (received > 0) 
      fprintf(fp,"%s",buffer);//strcat (rc, buffer); 

      if (received < readSize) 
      break; 
      //count++; 
     } 
    } 
    printf("\nFile saved!! %s !!!\n\n",filename); 
    fclose(fp); 
    return rc; 
} 

哦,我把它叫做這樣的:

char command[50]; 
sprintf(command,"GET /%s\r\n\r\n",relativepath); 
sslWrite (c, command); 
response = sslReadfile (c); 

其中C是我的連接。

回答

2

請勿使用fprintf來寫入二進制數據。使用fwrite。輸出較小的原因是fprintf正在第一個空字符處停止,跳過保留在1024字節緩衝區中的任何字符。此外,您似乎沒有使用緩衝區,也不需要使用緩衝區malloc d rc

因此,調用SSL_read後,你想是這樣的:

if (received <= 0) break; 
fwrite(buffer, 1, received, fp); 
+0

非常感謝。你解決了我的問題:)謝謝梅爾,下面的答案,我收到時不應該打破這個循環 2011-05-24 15:09:12

2

當收到< READSIZE你打破循環,而不是當收到< = 0,您已檢查,你應該只跳出循環SSL_shutdown()和/或SSL_get_error()。 此外,您不應該NUL終止您的緩衝區並使用fprintf,但使用fwrite時保持緩衝區原樣。您現在正在您的數據中引入不在那裏的NUL。