c - 在 C 中使用 OpenSSL 接收 http 响应消息

标签 c sockets openssl httpresponse

我在尝试接收网站的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

字段连接已拆分。为什么我的功能没有收到所有的响应消息?我在里面用了 do while 循环。请告诉我哪里出错了?谢谢。

最佳答案

没有错。这就是 TCP 的工作原理。它是一种流式传输,没有消息边界的概念。发送的字节数和读取的字节数之间没有一对一的关系。您的阅读接收任意字节,然后您负责根据需要进行处理。继续读取、缓冲和解析 HTTP 数据,直到发现响应结束(有关详细信息,请参阅 RFC 2616 Section 4.4 Message Length)。循环 SSL_pending() 是不够的(或不正确的)。

在这种情况下,您必须一次读取一个以 CRLF 分隔的行,直到到达指示响应 header 结尾的 CRLF/CRLF 对,然后您需要分析收到的 header 以了解是否响应body 是否存在以及如何读取它,因为它可能采用几种不同的编码格式之一。如果存在,您可以读取正文(边读边解码),直到到达 header 指定的正文结尾。

请参阅我在 my answer 中发布的伪代码回答以下问题:

Receiving Chunked HTTP Data With Winsock

也就是说,您真的不应该一开始就手动实现 HTTP(更不用说 HTTPS)了。从头开始实现 HTTP 并非微不足道,就此而言,SSL/TLS 也不是。在不了解网络编程和 OpenSSL 编程的一些重要基础知识的情况下,您已经一头扎进了一口深井中。您应该改用现有的 HTTP/S 库,例如 libcurl ,让它为您处理细节,这样您就可以专注于代码的业务逻辑,而不是它的通信逻辑。

关于c - 在 C 中使用 OpenSSL 接收 http 响应消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38596650/

相关文章:

c - 接收所有套接字(直到消息结束符号),C

python - 使用 python 2.7.9 安装 pip 时出现 HTTPSHandler 错误

c# - Diffie-Hellman 与 BIGNUM (OpenSSL) 与 BigInteger (C#)

c - 哈希算法的实现将字符串转换为数字

java - 使用 JNI 时出现 UnsatisfiedLinkError?

java - 等待套接字数据传输

c - 如何让消息在 1 秒后被丢弃? (C语言中的UDP客户端/服务器)

c - 在 C 中将代码行作为参数传递

c++ - 在 C、C++ 中通过移位运算符(<<、>>)移位的位

c - openssl pkcs12 命令以编程方式 Objective-C/C