返回
执行流程
见解分享
2023-12-16 15:32:53
## tinyhttpd 源码分析:2. 执行流程及主要函数浅析
tinyhttpd 的执行流程如下图所示:
[Image of tinyhttpd execution flow]
-
main() 函数:
- 首先调用
startup()
函数开启一个 TCP 服务器端口。 - 接收到请求后,
main()
函数会创建一个线程执行accept_request()
函数。
- 首先调用
-
accept_request() 函数:
- 从监听套接字中接受一个客户端连接。
- 为该连接创建一个新的线程,并调用
service()
函数。
-
service() 函数:
- 解析 HTTP 请求。
- 根据请求类型和路径调用适当的处理函数。
- 准备并发送响应。
tinyhttpd 使用的主要函数包括:
-
startup() 函数:
- 打开监听套接字并绑定到指定的端口。
- 初始化线程池。
- 初始化文件系统。
-
accept_request() 函数:
- 从监听套接字中接受一个客户端连接。
- 为该连接创建一个新的线程,并调用
service()
函数。
-
service() 函数:
- 解析 HTTP 请求。
- 根据请求类型和路径调用适当的处理函数。
- 准备并发送响应。
-
handle_file_request() 函数:
- 处理对静态文件的请求。
- 读取文件并将其发送给客户端。
-
handle_cgi_request() 函数:
- 处理对 CGI 脚本的请求。
- 执行 CGI 脚本并将输出发送给客户端。
以下是 startup()
函数的示例代码:
void startup(void)
{
struct sockaddr_in sa;
/* Open a listening socket */
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
perror("socket");
exit(1);
}
/* Bind the socket to the port */
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(PORT);
sa.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
perror("bind");
exit(1);
}
/* Start listening */
if (listen(s, 5) < 0) {
perror("listen");
exit(1);
}
/* Initialize the thread pool */
thread_pool_init();
/* Initialize the file system */
fs_init();
}