记录:GNU Libmicrohttpd介绍和使用

花阳辉
2023-12-01

1.GNU Libmicrohttpd是一个用来在项目中内嵌http服务器的C语言库。
2.特点
(1)C语言库,小而快。
(2)API非常简单,且都是可重入的。
(3)兼容HTTP1.1。
(4)支持4种多线程模型(select、poll、pthread、thread poll)。
(5)跨平台。
(6)生成的二制文件只有32K(不包含TLS/SSL等额外功能)。
3.编译调用
将其添加进项目中,生成一个头文件和一个静态库文件。调用时需要引用头文件和库文件两个文件。
4.main函数
main函数核心调用只有2个函数:MHD_start_daemon,MHD_stop_daemon,分别开始和停止http服务器。

int main()
{
	const int port = 8888;

	struct MHD_Daemon* daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, port , NULL, NULL,
	 												connectionHandler, NULL, MHD_OPTION_END);

	if (daemon == NULL) {	
		std::cout << "cannot start server!\n";	
		return -1;	
	}
	
	std::cin.get();	
	MHD_stop_daemon(daemon);
	
	return 0;	
}

MHD_start_daemon函数包含非常多的参数,这也意味着它集成了很多的功能,这里只关注四个参数,其它都为NULL:

(1)MHD_USE_INTERNAL_POLLING_THREAD。这个参数与其他两个参数(MHD_USE_POLL_INTERNAL_THREAD、MHD_USE_EPOLL_INTERNAL_THREAD)一起构成了microhttpd支持的三种模式:select、poll、epoll。用户必须选择其中之一。具体信息见源码。
(2)port。端口号。
(3)connectHandler。处理请求的函数。
(4)MHD_OPTION_END。由于MHD_start_daemon最后一个参数是一个变参,因此MHD_OPTION_END用来表示变参终止。
5.connectionHandler回调函数

int connectionHandler( 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 **con_cls)
{
	const char* pageBuffer = "<html><body>Hello, I'm lgxZJ!</body></html>";
	struct MHD_Response *response; 

	response = MHD_create_response_from_buffer(strlen(pageBuffer), (void*)pageBuffer,
												MHD_RESPMEM_PERSISTENT);

	if (MHD_add_response_header(response, "Content-Type", "text/html") == MHD_NO) {
		std::cout << "MHD_add_response_header error\n";
		return MHD_NO;
	}

	if (MHD_queue_response(connection, MHD_HTTP_OK, response) == MHD_NO) {
		std::cout << "MHD_queue_response error\n";
		return MHD_NO;
	}

	MHD_destroy_response(response);
	return MHD_YES;
}

这个函数签名包含了所有用来处理请求的有用信息。microhttpd库提供了函数来方便我们响应请求,这里重点看创建响应。microhttpd库提供了两种方法来创建请求:从buffer创建、从文件创建。但是后者需要传入一个文件描述符,这在windows上不是很方便。
这里用缓冲创建。需要注意的是最后一个参数,这是一个MHD_ResponseMemoryMode枚举值,表示使用的buffer内容是固定不变的。这种枚举类型还包含其他2种代表瞬时缓冲类型的值,分别表示缓冲区是在heap上的,和非heap(例如stack)上的。 用不同的缓冲区时要记得用不同的枚举值。 接下来设置MIME类型,把缓冲入队,并释放MHD_Response结构体。对于正确响应,返回MHD_YES;不能响应的,返回MHD_NO。

 类似资料: