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