2013-05-27 38 views
2

這是我的第一篇文章。我目前正在參加一個網絡課程,我需要編寫一個客戶端程序,可以將所有電子郵件從imap.gmail.com:993下載到文本文件。我需要使用winsock和openssl編寫這個程序。我能夠連接到服務器並獲取電子郵件。對於使用小數據的電子郵件,我無法接收它。但對於具有大量數據的電子郵件,如基於64位解碼的圖像,我只能下載其中的一部分。我如何告訴客戶等待它收到所有數據?

所以我的問題是我如何告訴客戶端等待,直到它收到服務器的所有數據?

這是我迄今所做的:

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(); 

    } 
} 
+0

我不熟悉這一點,但只是一個猜測,任何提高連接超時值的屬性,這可能會有所幫助。 – YvesR

+0

我不知道這個SSL庫,但通常TCP通信會將數據分解爲網絡中的數據包,並在數據可用時讀取返回的數據塊以便於早期處理。您通常可以使用'recv()'函數的函數參數來阻塞,直到讀取所有期望的字節(參數的MSG_WAITALL)。可能有某種方法可以讓SSL_read使用它,如果不是的話,你可能打算在一個循環中調用SSL_read,逐個組裝消息包,直到讀取所有預期的數據。請參閱http://www.openssl.org/docs/ssl/SSL_read.html - 它討論了這一點。 –

回答

1

首先在你的代碼的所有的一些要點:

  • 您使用的strcpy,strcat的和所有那些不加制止,不安全的C函數。你可能很容易得到緩衝區溢出和其他類型的錯誤。考慮使用C++字符串,向量,數組。
  • 在不同的抽象層次上,你在該函數中做了很多不同的事情。 AFAICS只有兩個SSL_ *函數調用真的是關於獲取該郵件。考慮打破一些功能,以提高可讀性。

現在你的問題:谷歌搜索了一下SSL_read,你會看到它返回一個int,表示實際讀取的字節數。您應該使用該返回值 - 不僅是針對此問題,還包括錯誤處理。如果郵件數據比緩衝區長,該函數將讀取,直到緩衝區填滿並返回其大小。您應該繼續調用該函數,直到讀取完所有字節。

相關問題