如何告诉客户端等到收到所有数据?

时间:2013-05-27 05:40:54

标签: c++ openssl imap winsock

这是我的第一篇文章。我目前正在上网络课程,我需要编写一个客户端程序,可以将imap.gmail.com:993的所有电子邮件下载到文本文件中。我需要使用winsock和openssl编写这个程序。我能够连接到服务器并获取电子邮件。对于包含小数据的电子邮件,我收到它没有问题。但对于具有大数据的电子邮件,例如base64解码的图像,我只能下载其中的一部分。

所以我的问题是如何告诉客户端等待它从服务器收到所有数据?

这是我到目前为止所做的:

void fetchMail(SSL *sslConnection,int lowerLimit, int UpperLimit)
 {
     SYSTEMTIME lt;
    ofstream outfile;
     GetLocalTime(&lt);
    char szFile[MAX_PATH + 1];
    char szPath[MAX_PATH+1];
    char message[BUFSIZE];
    char result[BUFSIZE];
    ::GetModuleFileName( NULL, szPath,  MAX_PATH );

    // Change file name to current full path
  LPCTSTR psz = strchr( szPath, '\\');
    if( psz != NULL )
    {
        szPath[psz-szPath] = '\0';
    }
    char szMailBox[MAX_PATH+1];
    memset( szMailBox, 0, sizeof(szMailBox));
    wsprintf( szMailBox, "%s\\inbox", szPath );

    // Create a folder to store emails
    ::CreateDirectory( szMailBox, NULL );
   for(int i = lowerLimit; i < UpperLimit; ++i)
   {
    // Create a folder to store emails

       memset( szFile, 0, sizeof(szFile));
       memset( result, 0, sizeof(result));
       memset( message, 0, sizeof(message));
       ::sprintf(szFile,"%s\\%d%d%d%d%d%d.txt", szMailBox, lt.wHour, lt.wMinute,lt.wMinute,lt.wSecond, lt.wMilliseconds,i);



    string Result;//string which will contain the result

    stringstream convert; // stringstream used for the conversion
    const char * num;
    convert << i;//add the value of Number to the characters in the stream

    Result = convert.str();//set Result to the content of the stream
    num = Result.c_str();


    strcpy(result, "tag FETCH ");
    strcat(result,  num);
    strcat(result, " (BODY[TEXT])\r\n");

    int n = 0;

    cout << "\nFETCHING : \n";

    SSL_write(sslConnection, result, strlen(result));
    outfile.open(szFile );

    SSL_read(sslConnection, message, sizeof(message)-1);

    outfile <<message ;


    outfile.close();

   }
 }

1 个答案:

答案 0 :(得分:1)

首先,代码中的一些要点:

  • 您使用strcpy,strcat和所有未经检查的,不安全的C函数。您可能很容易得到缓冲区溢出和其他类型的错误。考虑使用C ++字符串,向量,数组。
  • 在不同的抽象层次上,你在这个函数中做了很多不同的事情。 AFAICS只有两个SSL_ *函数调用真正关于获取该邮件。考虑打破一些功能以提高可读性。

现在你的问题:谷歌搜索SSL_read,你会看到它返回一个int,表示实际读取了多少字节。您应该使用该返回值 - 不仅针对此问题,还针对错误处理。如果邮件数据长于缓冲区,则该函数将一直读取,直到填充缓冲区并返回其大小。您应该继续调用该函数,直到读取完所有字节为止。