GNU Libmicrohttpd是一个用来在项目中内嵌http服务器的C语言库,它具备如下几个很是鲜明的特色:html
这篇文章里,咱们只编写一个简单的静态服务器,对于用户的全部请求咱们都只返回同一个html页面, 该页面显示一串字符。windows
为了使用Libmicrohttpd,咱们须要将其添加进VS项目中。这里咱们选择编译源代码生成静态库,由于官方给的下载静态库版本连接在使用时会有问题,多是运行库版本不一致; 而且在使用静态库的状况下,咱们只须要引用两个文件就能够了(一个头文件、一个库文件),项目结构不会混乱不清。浏览器
实际上Libmicrohttpd的源码编译很是简单,它提供了VS编译文件,基本上咱们只须要进入w32
目录,在该目录下选择合适的VS子目录下的sln文件,双击打开就能够了。打开后,修改设置libmicrohttpd项目为静态库项目(记得修改生成文件的后缀名,由于默认是dll),右击生成就能够编译成功了。服务器
生成的文件包括一个头文件和一个静态库文件,新建一个VS控制台项目,并将它们添加到VS项目中。多线程
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:url
MHD_stop_daemon函数比较简单,这里不介绍了。线程
全部的请求处理都发生在connectionHandler
中:code
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上不是很方便。server
咱们这里用缓冲建立。须要注意的是最后一个参数,这是一个MHD_ResponseMemoryMode
枚举值,表示咱们使用的buffer内容是固定不变的。这种枚举类型还包含其余2种表明瞬时缓冲类型的值,分别表示缓冲区是在heap上的,和非heap(例如stack)上的。 用不一样的缓冲区时要记得用不一样的枚举值。 接下来设置MIME类型,把缓冲入队,并释放MHD_Response结构体。对于正确响应,咱们返回MHD_YES;不能响应的,咱们返回MHD_NO。
运行程序,咱们打开浏览器并输入127.0.0.1:8888
,获得以下结果:
MHD_start_daemon
函数还能够限制特定ip的访问。