1.部署libmicrohttpd(问豆包)
2.头文件
#include <thread>
#include <fstream>
#include <vector>
#include <sstream>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <algorithm>
#include <cstring>
#include <microhttpd.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/socket.h>
3.定义本地端口
#define XZvisionPORT 8888
4.固定请求
cpp
int answer_to_connection (void *cls, struct MHD_Connection *connection,
const char *url,
const char *method, const char *version,
const char *upload_data,
size_t *upload_data_size, void **req_cls)
{
const char *page = "<html><body>Hello, browser!</body></html>"; // 定义一个HTML页面的内容
struct MHD_Response *response; // 声明一个MHD响应结构体指针
int ret; // 声明一个整型变量用于存储返回值
response = MHD_create_response_from_buffer (strlen (page), // 创建一个持久化的HTTP响应,使用之前定义的HTML内容
(void*) page, MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response); // 将响应加入队列,返回HTTP 200 OK状态码
MHD_destroy_response (response); // 销毁响应对象,释放资源
return ret; // 返回操作结果
}
int main()
{
//自己去掉注释
// struct MHD_Daemon *daemon;
// daemon = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD| MHD_USE_PEDANTIC_CHECKS, XZvisionPORT, NULL, NULL,&answer_to_connection, NULL, MHD_OPTION_END);
// if (NULL == daemon) return 1;
// getchar ();
// MHD_stop_daemon (daemon);
// return 0;
}
5.终端给内容
cpp
int answer_to_connection1(void *cls, struct MHD_Connection *connection,
const char *url,
const char *method, const char *version,
const char *upload_data,
size_t *upload_data_size, void **req_cls)
{
const char* text = (const char*)cls;
// 生成 HTML,**指定 UTF-8 编码,解决中文乱码!**
char buf[2048];
snprintf(buf, sizeof(buf),
"<html><head><meta charset='utf-8'></head><body>%s</body></html>",
text);
struct MHD_Response *response;
response = MHD_create_response_from_buffer(
strlen(buf), buf, MHD_RESPMEM_MUST_COPY);
int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
MHD_destroy_response(response);
return ret;
}
int main()
{
// std::string user_text;
// std::cout << "请输入要显示的文字:";
// std::getline(std::cin, user_text); // 输入一整行
// struct MHD_Daemon *daemon;
// daemon = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD| MHD_USE_PEDANTIC_CHECKS, XZvisionPORT, NULL, NULL,&answer_to_connection1, (void*)user_text.c_str(), MHD_OPTION_END);
// if (NULL == daemon) return 1;
// getchar ();
// MHD_stop_daemon (daemon);
// return 0;
}
6.显示时间
cpp
char* get_current_time()
{
// 获取系统时间
time_t now = time(nullptr);
char* time_str = ctime(&now);
// 分配新内存,返回给服务器
char* result = new char[strlen(time_str) + 1];
strcpy(result, time_str);
return result; // 返回字符串
}
/*显示实时时间------刷新
struct MHD_Daemon* daemon;
// ==============================
// 第六个参数传递【函数地址】!
// ==============================
daemon = MHD_start_daemon(
MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_PEDANTIC_CHECKS,
8888,
NULL, NULL,
&answer_to_connection2,
(void*)get_current_time, // ✅ 传入函数指针
MHD_OPTION_END);
if (!daemon) {
cerr << "服务器启动失败!" << endl;
return 1;
}
cout << "服务器已启动:http://127.0.0.1:8888" << endl;
cout << "每次刷新页面都会更新时间!" << endl;
getchar();
MHD_stop_daemon(daemon);
return 0;*/
int answer_to_connection2(
void* cls, // 这里 cls = 函数指针 get_current_time
struct MHD_Connection* connection,
const char* url,
const char* method,
const char* version,
const char* upload_data,
size_t* upload_data_size,
void** req_cls)
{
// ==============================
// 1. 把 cls 转回函数指针
// ==============================
char* (*get_info_func)() = (char*(*)())cls;
// ==============================
// 2. 每次请求都调用函数,获取新时间
// ==============================
char* info = get_info_func();
// ==============================
// 3. 包装成 HTML(UTF8 中文不乱码)
// ==============================
char html[2048];
snprintf(html, sizeof(html),
"<html><head><meta charset='utf-8'></head>"
"<body><h1>当前服务器时间:%s</h1></body></html>",
info);
// 发送响应
struct MHD_Response* response = MHD_create_response_from_buffer(
strlen(html), html, MHD_RESPMEM_MUST_COPY);
int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
MHD_destroy_response(response);
// ==============================
// 4. 【关键】释放内存!不泄漏!
// ==============================
delete[] info;
return ret;
}
int main()
{
// struct MHD_Daemon *daemon;
// daemon = MHD_start_daemon(
// MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_PEDANTIC_CHECKS,
// 8888,
// NULL, NULL,
// &answer_to_connection3,
// NULL,
// MHD_OPTION_END);
// if (!daemon) {
// cerr << "服务器启动失败!" << endl;
// return 1;
// }
// cout << "服务器已启动 : 端口 8888" << endl;
// cout << "现在用浏览器访问,会打印所有请求信息!" << endl;
// getchar();
// MHD_stop_daemon(daemon);
// return 0;
}
7.分级跳转
cpp
// 发送 HTML 响应(中文不乱码)
static int send_html(struct MHD_Connection *conn, const char *html)
{
struct MHD_Response *resp = MHD_create_response_from_buffer(
strlen(html), (void*)html, MHD_RESPMEM_PERSISTENT);
// ✅ 关键:告诉浏览器用 UTF-8 解析
MHD_add_response_header(resp, "Content-Type", "text/html; charset=utf-8");
int ret = MHD_queue_response(conn, MHD_HTTP_OK, resp);
MHD_destroy_response(resp);
return ret;
}
// 发送 404 响应
static int send_404(struct MHD_Connection *conn)
{
const char *page = "<html><head><meta charset=utf-8></head><body><h1>404 页面未找到</h1></body></html>";
struct MHD_Response *resp = MHD_create_response_from_buffer(
strlen(page), (void*)page, MHD_RESPMEM_PERSISTENT);
MHD_add_response_header(resp, "Content-Type", "text/html; charset=utf-8");
int ret = MHD_queue_response(conn, MHD_HTTP_NOT_FOUND, resp);
MHD_destroy_response(resp);
return ret;
}
static int answer_to_connection4(
void *cls,
struct MHD_Connection *connection,
const char *url,
const char *method,
const char *version,
const char *upload_data,
size_t *upload_data_size,
void **req_cls)
{
// 只处理 GET
if (strcmp(method, "GET") != 0) {
return MHD_NO;
}
// ======================
// 首页 /index.html
// ======================
if (strcmp(url, "/index.html") == 0 || strcmp(url, "/index.htm") == 0) {
const char *page =
"<html>"
"<head><meta charset=\"utf-8\"></head>"
"<body>"
"<h1>虚拟首页</h1>"
"<p>这是动态生成的 index.html</p>"
"<a href=\"/another.html\">跳转到 another.html</a>"
"</body>"
"</html>";
return send_html(connection, page);
}
// ======================
// 另一个页面 /another.html
// ======================
else if (strcmp(url, "/another.html") == 0) {
const char *page =
"<html>"
"<head><meta charset=\"utf-8\"></head>"
"<body>"
"<h1>第二个页面</h1>"
"<p>这是动态生成的 another.html</p>"
"<a href=\"/index.html\">返回首页</a>"
"</body>"
"</html>";
return send_html(connection, page);
}
// ======================
// 404
// ======================
else {
return send_404(connection);
}
return MHD_NO;
}
int main()
{
struct MHD_Daemon *daemon;
daemon = MHD_start_daemon(
MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_PEDANTIC_CHECKS,
8888,
NULL, NULL,
&answer_to_connection4,
NULL,
MHD_OPTION_END);
if (!daemon) {
cerr << "服务器启动失败!" << endl;
return 1;
}
cout << "服务器已启动 : 端口 8888" << endl;
cout << "现在用浏览器访问,会打印所有请求信息!" << endl;
getchar();
MHD_stop_daemon(daemon);
return 0;
}