2

这是我的第一篇文章。我目前正在学习网络课程,我需要编写一个客户端程序,可以将 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();

   }
 }
4

1 回答 1

1

首先,您的代码有几点:

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

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

于 2013-05-27T06:02:33.377 回答