2016-07-26 24 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 

フィールドの接続が分割されました。なぜ私の機能がすべての応答メッセージを受信しなかったのですか?私は内部をループしていました。どこが間違っていたのか教えてください。ありがとうございました。

答えて

2

何も問題ありません。これは単にTCPがどのように動作するかです。これはストリーミング転送であり、メッセージ境界という概念はありません。送信されたバイト数と読み取られたバイト数との間に1対1の関係はありません。あなたの読書は任意のバイトを受け取り、それはあなたが必要に応じて処理を担当します。レスポンスの終わりを見つけるまで、HTTPデータの読み込み、バッファリング、および解析を続けます(詳細はRFC 2616 Section 4.4 Message Lengthを参照)。 SSL_pending()のルーピングでは不十分です(または正しい)。

この場合、応答ヘッダーの終わりを示すCRLF/CRLFのペアに達するまで、一度に1つずつCRLF区切りの行を読み取る必要があります。次に、受け取ったヘッダーを分析して、いくつかの異なるエンコードされたフォーマットのいずれかにある可能性があるため、レスポンスボディが存在し、それをどのように読み取るかが決まります。存在する場合は、ヘッダーで指定されている本文の末尾に達するまで、本文を読むことができます。手動で開始するには、あなたが本当に(おろかHTTPS)をHTTPを実装すべきではない、と述べた

Receiving Chunked HTTP Data With Winsock

、私は次の質問に my answerに投稿された疑似コードを参照してください。 HTTPは であり、はゼロから実装するのが簡単ではなく、SSL/TLSはどちらも問題ありません。ネットワークプログラミングとOpenSSLプログラミングの重要な基礎を理解することなく、頭を掘り下げて深い井戸に飛び出しました。 libcurlのような既存のHTTP/Sライブラリを代わりに使用し、詳細を処理させて、コードのビジネスロジックではなく通信ロジックに集中できるようにする必要があります。

+0

ありがとうございました。すぐにお返事します。 – thanhdx

+0

こんにちは、もっと情報を読んだ後で、まだ質問があります: – thanhdx

+0

- CRLFまでテキストの行を読み込むにはどうすればよいですか? SSL_read()はバッファーをバイト単位で読み取ります。私はバイトをバッファに読み込み、それを解析して各行を処理する必要がありますか?または、CRLFまでバイトを1つずつ読み込みます(おそらく遅く実行されます)?それとも何か? – thanhdx

関連する問題