读alhttpd有感
读了下althttpd的源代码,想研究下 one-process-one-connection 模型的服务器具体是咋实现,结果核心代码也就 20 来行(省略了外头的while(1)
和变量声明):
select( maxFd+1, &readfds, 0, 0, &delay);
for(i=0; i<n; i++){
if( FD_ISSET(listener[i], &readfds) ){
lenaddr = sizeof(inaddr);
connection = accept(listener[i], &inaddr.sa, &lenaddr);
if( connection>=0 ){
child = fork();
if( child!=0 ){
if( child>0 ) nchildren++;
close(connection);
printf("subprocess %d started...\n", child); fflush(stdout);
}else{
int nErr = 0, fd;
close(0);
fd = dup(connection);
if( fd!=0 ) nErr++;
close(1);
fd = dup(connection);
if( fd!=1 ) nErr++;
close(connection);
return nErr;
}
}
}
}
流程异常简单:
- 父进程:
select
=>accept
=> 计数 => 关闭 connection 的 fd =>select
- 子进程:把
stdin
和stdout
都替换成 connection 的 fd => 跳出循环 => 处理 req/res
先不考虑多进程带来的性能问题,这个设计实在是简洁和漂亮:子进程直接读stdin
处理 request;子进程直接写stdout
处理 response;子进程遇到异常直接exit
就 OK 了,没有 leak 烦恼,安全性也好处理,还不影响主进程继续处理后续请求。
原谅我没咋度过 linux 的服务器源代码,直接把子进程的stdin
和stdout
替换成 socket fd 这个设计还是让我“大惊小怪”了一把,everything is file
yyds!设计 Unix 的先贤们 yyds!