在C中通过SSL下载文件

时间:2011-05-24 14:34:19

标签: c ssl

我必须在C中编写一个连接到服务器的SSL客户端,并获取一个html,或者一个文件。我设法获得了HTML,但我无法下载二进制文件。例如,我正在尝试从https://www.openssl.org/source/openssl-1.0.0d.tar.gz下载一个3.8mb文件,我的代码只设法下载它们的1.1mb,我甚至不知道我是否在其中获得了正确的数据。

这是我为它做的功能:

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 个答案:

答案 0 :(得分:2)

不要使用fprintf来写二进制数据。使用fwrite。输出较小的原因是fprintf在第一个空字符处停止,跳过保留在1024字节缓冲区中的任何字符。此外,您似乎没有使用,也不需要malloc d rc缓冲区。

因此,在致电SSL_read之后,您需要这样的内容:

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

答案 1 :(得分:2)

你收到时打破了循环&lt; readSize,相反,你应该只在收到&lt; = 0时断开循环,并且你已经检查了SSL_shutdown()和/或SSL_get_error()。 此外,您不应该NUL终止缓冲区并使用fprintf,但在使用fwrite时保持缓冲区不变。您现在正在数据中引入NUL而不是那里。