2016-07-26 62 views
0

嘗試接收網站的http響應消息時遇到一些問題。
這是我的函數:在C中使用OpenSSL接收http響應消息

void Reveive_response(char *resp, SSL *ssl) { 

    const int BUFFER_SIZE = 1024; 
    char response[1048576]; 
    char *buffer = NULL;   // to read from ssl 
    char *check = (char *) malloc(BUFFER_SIZE*sizeof(char)); 
    int bytes;      // number of bytes actually read 
    int received = 0;    // number of bytes received 

    buffer = (char *) malloc(BUFFER_SIZE*sizeof(char));  // malloc 
    memset(response, '\0', sizeof(response));    // response 
    assign = '\0' 
    do{ 
     memset(buffer, '\0', BUFFER_SIZE);   // empty buffer 
     bytes = SSL_read(ssl, buffer, BUFFER_SIZE); 
     if (bytes < 0) { 
      printf("Error: Receive response\n"); 
      exit(0); 
     } 
     if (bytes == 0) break; 
     received += bytes; 
     printf("Received...%d bytes\n", received); 
     strncat(response, buffer, bytes); // concat buffer to response 
    } while (SSL_pending(ssl));    // while pending 
    response[received] = '\0'; 
    printf("Receive DONE\n"); 
    printf("Response: \n%s\n", response); 
    free(buffer); 
    strcpy(resp, response);     // return via resp 

} 

當我調用該函數,這似乎是響應消息是不完整的。就像這樣:

Received...1014 bytes 
Received...1071 bytes 
Receive DONE 
Response: 
HTTP/1.1 200 OK 
<... something else....> 
Vary: Accept-Encoding 
Content-Type: text/html 
Conne 

那麼,如果我再次調用該函數,它返回:

Received...39 bytes 
Receive DONE 
Response: 
ction: keep-alive 
Content-Length: 0 

中的現場連接被分裂。爲什麼我的功能沒有收到所有的回覆信息?我用while循環裏面。請告訴我我哪裏錯了?謝謝。

回答

2

沒有什麼錯。這只是TCP的工作原理。它是一個流式傳輸,它沒有消息邊界的概念。發送的字節數與讀取的字節數之間沒有1對1的關係。您的閱讀收到任意字節,然後根據需要負責處理。繼續閱讀,緩衝和解析HTTP數據,直到您發現響應結束(有關詳細信息,請參閱RFC 2616 Section 4.4 Message Length)。循環SSL_pending()是不夠的(或正確的)。

在這種情況下,您必須一次讀取一個CRLF分隔的行,直到您到達指示響應標頭結尾的CRLF/CRLF對,然後您需要分析收到的標頭以瞭解響應體存在以及如何閱讀它,因爲它可能是幾種不同的編碼格式之一。如果存在,您可以隨時閱讀身體(隨身解碼),直到按照標題指定的方式到達身體的盡頭。

見僞代碼,我張貼在my answer以下問題:

Receiving Chunked HTTP Data With Winsock

這就是說,你真的不應該執行HTTP(更不用說HTTPS)手動開始說起。 HTTP是而不是從頭開始實施並不重要,SSL/TLS也不是這個問題。如果不瞭解網絡編程和OpenSSL編程的一些重要基礎知識,您就會先深入探究。您應該使用現有的HTTP/S庫(如libcurl),並讓它爲您處理細節,以便您可以專注於代碼的業務邏輯而不是其通信邏輯。

+0

謝謝。我會盡快回復你。 – thanhdx

+0

嗨,閱讀更多信息後,我仍然有一些問題: – thanhdx

+0

- 如何閱讀一行文字直到CRLF? SSL_read()按字節讀取緩衝區。我應該讀取字節緩衝區然後解析它來處理每一行?或者逐個讀取字節直到CRLF(它可能運行得很慢)?還是其他什麼? – thanhdx