2016-07-26 2 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 쌍에 도달 할 때까지 한 번에 하나씩 CRLF로 구분 된 행을 읽어야합니다. 그런 다음 수신 한 헤더를 분석하여 응답 본문은 여러 다른 인코딩 된 형식 중 하나 일 수 있으므로 현재 읽거나 읽는 방법을 보여줍니다. 헤더가있는 경우 본문이 끝날 때까지 본문을 읽을 수 있습니다 (진행하면서 해독 할 수 있습니다). 수동으로 시작하는 당신이 정말로 (고사하고 HTTPS)을 HTTP를 구현하지 않아야 말했다

Receiving Chunked HTTP Data With Winsock

:

나는 다음과 같은 질문에 my answer에 게시 된 의사 코드를 참조하십시오. HTTP는 이 아니며은 처음부터 구현하기가 쉽지 않으며 SSL/TLS도 그다지 중요하지 않습니다. 네트워크 프로그래밍과 OpenSSL 프로그래밍의 몇 가지 중요한 기본 사항을 이해하지 못하면서 머리를 우물에 깊이 빠져 들었습니다. 기존의 HTTP/S 라이브러리 (예 : libcurl)를 대신 사용하여 세부 정보를 처리하도록하면 통신 논리가 아닌 비즈니스 로직에 초점을 맞출 수 있습니다.

+0

감사합니다. 나는 곧 당신에게 대답하려고 노력할 것이다. – thanhdx

+0

안녕하세요, 더 많은 정보를 읽은 후에도 여전히 질문이 있습니다. – thanhdx

+0

- CRLF까지 텍스트 줄을 읽으려면 어떻게해야합니까? SSL_read()는 버퍼를 바이트 단위로 읽습니다. 버퍼에 바이트를 읽고 각 행을 처리하기 위해 파싱해야합니까? 또는 CRLF (아마도 너무 느리게 실행될 때까지 하나씩 바이트를 읽으십시오)? 아니면 다른 것? – thanhdx

관련 문제