一、引言:HTTP与HTTPS是什么?
HTTP(HyperText Transfer Protocol) 是互联网上应用最广泛的协议之一,用于客户端(如浏览器)与服务器之间的通信。它基于明文传输,简单高效,但缺乏安全性。
HTTPS(HTTP Secure) 则是HTTP的安全版本,通过SSL/TLS协议对通信内容进行加密,确保数据在传输过程中不被窃取或篡改,广泛应用于支付、登录等敏感场景。
用一个生活化的比喻来理解:
HTTP 就像寄送明信片——内容公开,任何人都能看到和修改。
HTTPS 则像用加密保险箱寄送机密文件——只有收件人有钥匙,确保内容安全。
二、核心区别:HTTP vs HTTPS
特性 | HTTP | HTTPS |
---|---|---|
加密 | 无 | 对称加密 + 非对称加密(SSL/TLS) |
默认端口 | 80 | 443 |
证书 | 无需证书 | 需CA机构颁发的数字证书 |
数据安全 | 易被窃听、篡改 | 防窃听、防篡改、身份验证 |
性能 | 低延迟 | 略高延迟(加密/解密开销) |
三、协议格式详解
无论是HTTP还是HTTPS,应用层的数据格式是相同的,但HTTPS会在传输前加密数据。
1. HTTP请求格式
POST /api/data HTTP/1.1 ← 请求行(方法 + 路径 + 协议版本)
Host: www.example.com ← 头部字段(键值对)
Content-Type: application/json
Content-Length: 23 ← 必须声明正文长度
{"data": "hello world"} ← 正文(Body)
2. HTTP响应格式
HTTP/1.1 200 OK ← 状态行(版本 + 状态码 + 原因短语)
Content-Type: text/html
Content-Length: 34
<html>Welcome to example.com</html>
3. HTTPS加密后的数据包结构
复制
+---------------------+---------------------+ | TLS Record Header | Encrypted Data | +---------------------+---------------------+ | TLS版本、类型、长度 | 加密后的HTTP原始数据 |
加密过程:通过TLS握手协商对称密钥,后续通信使用对称加密(如AES)保护数据。
关键点:加密后的数据在传输层(TCP)不可读 ;只有通过TLS握手建立的对称密钥才能解密。
4. 关键字段说明
字段名 | 作用 |
---|---|
Content-Length |
正文长度(字节) |
Transfer-Encoding |
分块传输(chunked) |
Connection |
Keep-Alive 或 Close |
Cookie |
客户端携带的Cookie数据 |
四、关键协议细节
1. 分块传输编码(Chunked Encoding)
当响应长度未知时使用:
HTTP/1.1 200 OK
Transfer-Encoding: chunked
7\r\n ← 第一个块的长度(十六进制)
Chunk1\r\n
3\r\n
End\r\n
0\r\n ← 结束标志
\r\n
2. 状态码分类
范围 | 类别 | 示例 |
---|---|---|
1xx | 信息响应 | 100 Continue |
2xx | 成功 | 200 OK |
3xx | 重定向 | 301 Moved Permanently |
4xx | 客户端错误 | 404 Not Found |
5xx | 服务器错误 | 503 Service Unavailable |
五、C++代码示例:手动解析HTTP请求
以下代码模拟解析原始HTTP请求数据:
#include <iostream>
#include <string>
#include <sstream>
#include <map>
// 解析HTTP请求的简单实现
void parse_http_request(const std::string& raw_data) {
std::istringstream stream(raw_data);
std::string line;
// 1. 解析请求行
std::getline(stream, line);
std::cout << "Request Line: " << line << std::endl;
// 2. 解析头部
std::map<std::string, std::string> headers;
while (std::getline(stream, line) {
if (line.empty() || line == "\r") break; // 头部结束
size_t colon_pos = line.find(':');
if (colon_pos != std::string::npos) {
std::string key = line.substr(0, colon_pos);
std::string value = line.substr(colon_pos + 2); // 跳过": "
headers[key] = value;
}
}
// 3. 输出头部
std::cout << "\nHeaders:" << std::endl;
for (const auto& [key, value] : headers) {
std::cout << key << ": " << value << std::endl;
}
// 4. 解析正文
size_t body_start = raw_data.find("\r\n\r\n");
if (body_start != std::string::npos) {
std::string body = raw_data.substr(body_start + 4);
std::cout << "\nBody:\n" << body << std::endl;
}
}
int main() {
// 模拟原始HTTP请求数据
std::string http_request =
"POST /api/login HTTP/1.1\r\n"
"Host: www.example.com\r\n"
"User-Agent: C++Parser/1.0\r\n"
"Content-Type: application/json\r\n"
"Content-Length: 27\r\n"
"\r\n"
"{\"user\":\"admin\",\"pass\":\"123\"}";
parse_http_request(http_request);
return 0;
}
输出:
六、C++代码示例:主流开源库代码
我们将使用两个流行的开源库演示:
libcurl(简单易用)
Boost.Beast(高性能、底层控制)
示例1:使用libcurl发送HTTP/HTTPS请求
#include <iostream>
#include <curl/curl.h>
// 回调函数,处理接收到的数据
size_t write_callback(char* ptr, size_t size, size_t nmemb, void* userdata) {
std::string* response = (std::string*)userdata;
response->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
CURL* curl = curl_easy_init();
std::string response;
if (curl) {
// 设置目标URL(HTTP或HTTPS)
curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
// 针对HTTPS的额外配置
#ifdef SKIP_PEER_VERIFICATION
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); // 不验证证书(危险!仅用于测试)
#endif
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
std::cerr << "Curl failed: " << curl_easy_strerror(res) << std::endl;
} else {
std::cout << "Response:\n" << response << std::endl;
}
curl_easy_cleanup(curl);
}
return 0;
}
编译命令(Linux):
g++ -o curl_example curl_example.cpp -lcurl
示例2:使用Boost.Beast实现HTTPS客户端
#include <boost/beast.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl/stream.hpp>
#include <iostream>
namespace beast = boost::beast;
namespace http = beast::http;
namespace net = boost::asio;
namespace ssl = net::ssl;
int main() {
try {
// 1. 初始化SSL上下文
ssl::context ctx(ssl::context::tlsv12_client);
ctx.set_default_verify_paths(); // 加载系统证书
// 2. 创建IO上下文和SSL流
net::io_context ioc;
ssl::stream<net::ip::tcp::socket> stream(ioc, ctx);
// 3. 解析域名
net::ip::tcp::resolver resolver(ioc);
auto const results = resolver.resolve("www.example.com", "443");
// 4. 建立连接
net::connect(stream.next_layer(), results.begin(), results.end());
stream.handshake(ssl::stream_base::client);
// 5. 构造HTTP请求
http::request<http::string_body> req{http::verb::get, "/", 11};
req.set(http::field::host, "www.example.com");
req.set(http::field::user_agent, "Boost.Beast HTTPS Example");
// 6. 发送请求并读取响应
http::write(stream, req);
beast::flat_buffer buffer;
http::response<http::dynamic_body> res;
http::read(stream, buffer, res);
// 7. 输出结果
std::cout << "Response Code: " << res.result_int() << std::endl;
std::cout << "Body:\n" << beast::make_printable(res.body().data()) << std::endl;
} catch (std::exception const& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
编译命令(需要安装Boost和OpenSSL):
g++ -o beast_https beast_https.cpp -lboost_system -lssl -lcrypto
七、性能对比
场景 | HTTP延迟 | HTTPS延迟 |
---|---|---|
短连接 | 100ms | 200ms |
长连接 | 持续低 | 初始高,后续低 |
优化建议:
启用HTTP/2(多路复用)
会话复用(TLS Session Resumption)
八、总结
HTTP:适合内网通信、不敏感数据(如天气API)
HTTPS:必须用于登录、支付等敏感场景
C++实现:优先使用成熟库(libcurl/Boost.Beast),避免手写加密逻辑