2011-05-24 69 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。