多进程版本相对也很简单, 父进程负责接收和转换套接字, 接收后 Fork 出子进程去处理页面请求和返回所需求的页面.
首先是父进程:
父进程 Accept 后不对请求进行处理, 而是直接关闭所连接的套接字
这是因为 for 后, 父子进程间的文件描述符只是拷贝, 他们都指向同一个套接字, 对父进程来说, 这个主动套接字是多余的, 自己不会去里面读里面的数据, 因此可以直接关闭.
而由于文件中存在引用计数, 对该套接字文件来说, 虽然父进程关闭了该文件, 但实际上该文件的引用计数并未清 0, 实际仍然存在.
对于子进程:
对于子进程来说同样如此, 它的任务是处理套接字内的请求和返回所需要的资源, 监听套接字并不是它的任务, 因此首先需要先关闭监听套接字文件, 同理, 监听套接字文件由于文件计数的存在, 在父子进程都关闭前是不会关闭的.
关闭监听套接字后, 执行处理, 处理完毕后退出, 并由父进程的信号处理函数收尸.
对一个页面的请求, 会发送多个 HTTP 包请求资源:
通过在服务端打印文件名 filename 可以发现, 第一个请求是所求的资源, 但会发现针对这个页面父进程还会 fork 多次, 后续的资源打印出来发现是 CSS 等文件, 应该是浏览时所需的排版等信息 (猜测, 不太了解 CSS), 在 GDB 调试中发现也是如此, 在接受处理掉第一个 HTTP 包后马上关闭服务器, 会发现客户端浏览器能显示该页面的文字, 但排版, 字体等出现问题.
来源: http://www.bubuko.com/infodetail-3115697.html