本周 web 课的课程作业是实现一个类似 top
命令的网络服务,用于监控远程服务器的进程,其中使用的 web 服务器是 Libmicrohttpd
,于是在此记录下我的下载安装流程,如有错误,欢迎指正!
1. Libmicrohttpd
Libmicrohttpd 是一个小型的 C 语言库,用于嵌入 HTTP 服务器功能到应用程序中。
它支持 HTTP 1.1,可在 Unix-like 系统(如 Linux)和 Windows 上运行,它还提供简单的编程接口,用于监听网络连接、解析 HTTP 请求和发送响应。
以下是在 CentOS 7 上下载、配置、编译并安装 Libmicrohttpd 的详细步骤:
2. 准备工作
安装依赖工具和库 :确保系统具有编译源代码所需的基本工具和库,可以通过以下命令安装:
sudo yum groupinstall "Development Tools"
sudo yum install libtool libgcrypt-devel gnutls-devel
Development Tools :是一组工具,包括编译器、链接器、调试器等,它们是编译和构建软件的基础。(比如 gcc,make 等)
Libtool :是一个用于创建可移植库的脚本,与在不同系统上创建共享库(动态链接库)相关
Libgcrypt-devel :是 Libgcrypt 的开发文件(头文件和库),用于提供加密功能
Gnutls-devel :是 GnuTLS(一个安全通信库)的开发版本,它提供了网络通信中的加密和安全功能,例如支持 HTTPS
3. 下载和解压
wget https://ftp.gnu.org/gnu/libmicrohttpd/libmicrohttpd-latest.tar.gz
tar -xzvf libmicrohttpd-latest.tar.gz
4. 编译和安装
可以使用 ./configure
命令来配置 Libmicrohttpd,如
--prefix=PATH
:指定软件安装的目录,默认通常是安装到 /usr/local
目录下
--enable-或-disable-OPTION
:启用或禁用特定的功能或选项,例如:./configure --enable-https=yes
可以开启 HTTPS 支持
cd libmicrohttpd-0.9.77
./configure --prefix=/usr/local
5. 验证安装
验证安装 :验证 Libmicrohttpd 是否正确安装
pkg-config --libs --cflags libmicrohttpd
如果安装正确,这个命令会输出库的版本和编译选项
如果和我一样输出的不太对,也就是类似下面这样:Package libmicrohttpd was not found in the pkg-config search path. Perhaps you should add the directory containing libmicrohttpd.pc' to the PKG_CONFIG_PATH environment variable No package 'libmicrohttpd' found
那就接着配置下面的环境变量
6. 设置环境变量
设置 PKG_CONFIG_PATH
环境变量 :执行以下命令将 /usr/local/lib/pkgconfig
添加到 PKG_CONFIG_PATH
环境变量中
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
验证设置 :再次运行 pkg-config
命令来检查 Libmicrohttpd 是否能被正确识别:
pkg-config --libs --cflags libmicrohttpd
如果一切顺利,这次命令应该能输出 Libmicrohttpd 的链接和编译选项,然后我们就将环境变量永久添加到配置文件中
永久添加环境变量 :为了确保这个环境变量在每次登录或开机时都被自动设置,需要将这个 export
命令添加到 shell 配置文件中,如 ~/.bashrc
echo 'export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH' >> ~/.bashrc
使更改生效 :为了使 .bashrc
中的更改立即生效,执行以下命令:
7. 运行测试代码
先编写一个简单的小demo,用于获取系统top命令的输出并生成HTML页面返回响应
#include <microhttpd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#define PORT 8888
static 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 **con_cls) {
char *page;
FILE *fp;
char path[1035 ];
fp = popen("top -b -n 1" , "r" );
if (fp == NULL ) {
printf ("Failed to run command\n" );
exit (1 );
}
size_t page_size = 10000 ;
page = malloc (page_size);
if (!page) {
perror("Malloc failed" );
exit (1 );
}
strcpy (page, "<html><head><meta charset=\"UTF-8\"></head><body>" );
while (fgets(path, sizeof (path)-1 , fp) != NULL ) {
if (strlen (page) + strlen (path) + 8 > page_size) {
page_size *= 2 ;
char *new_page = realloc (page, page_size);
if (!new_page) {
perror("Realloc failed" );
free (page);
exit (1 );
}
page = new_page;
}
strcat (page, path);
strcat (page, "<br>" );
}
strcat (page, "</body></html>" );
struct MHD_Response *response ;
int ret;
response = MHD_create_response_from_buffer(strlen (page), (void *)page, MHD_RESPMEM_MUST_FREE);
ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
MHD_destroy_response(response);
pclose(fp);
return ret;
}
int main () {
struct MHD_Daemon *daemon ;
daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, PORT, NULL , NULL ,
(MHD_AccessHandlerCallback) answer_to_connection, NULL , MHD_OPTION_END);
if (NULL == daemon) return 1 ;
getchar();
MHD_stop_daemon(daemon);
return 0 ;
}
gcc test.c -o test -lmicrohttpd
./test
error while loading shared libraries: libmicrohttpd.so.12: cannot open shared object file: No such file or directory
那就继续下面的步骤
8. 解决运行时库加载的问题
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
gcc test.c -o test -lmicrohttpd
./test
9. 卸载 Libmicrohttpd
如果需要卸载重试的话,可以尝试下面的命令
进入之前编译 Libmicrohttpd 的目录
执行卸载命令:
可选:清理环境变量配置(从 .bashrc
中删除相关行)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端