http服务器的实现逻辑
1.实现基于 tcp 协议的服务器端(创建监听套接字 bind; listen )
注:
http协议属于应用层协议,其功能的实现依赖于下层结构提供的服务。它的无连接特性决定了它的下层必须保证 单次交互的可靠性(否则 本来就一次性,还不知道可靠不可靠(获取的数据是否正确有序),谁用?)。而tcp协议刚好提供了这种可靠性。但是tcp协议是面向连接的,因此 ,在后续的逻辑中,在一次交互完成后,需要关闭连接。
http的请求报文:
http的响应报文:
2.主线程循环 accept 建立连接,成功后创建子线程处理后续逻辑。主线程继续accept
3.子线程 处理:
1>
获取请求行 分别 截取 method url version ,在此要通过判断是不是\r\n 表示一行结尾。用到recv函数中的MSG_PEEK方法
2>
对正确的 请求行 进行处理
(1)
get方法无参数(非 CGI) 回复 请求资源。(在此用sendfile函数提高效率)
(2)
get方法有参数(url中含‘?’之后为参数(从含表单的网页页面获取)),先将参数作为环境变量。fork子进程(子进程共享父进程的环境变量)。子进程 程序 替换 为 真实的 可执行程序 (‘?’之前的url) 对参数做处理得到执行结果,通过管道 传给 父进程,父进程对数据做差错检测后,发送给客户端。
注:将参数作为环境变量 使用:
putenv(char*);上传环境变量
getenv (char*);获取环境变量
(3)
post方法 一定含有参数。参数的有效长度包含在消息报头中
例:
Content-Length:22 (CRLF)
将其作为换境变量,fork子进程。子进程exec 为 请求的可执行程序,通过管道 在sock中的请求正文中读取给定数量的字符,并处理。将处理结果通过管道发送给父进程,父进程 检测后 发送给客户端
CGI处理逻辑图:
整体的逻辑:
三、运行结果截图: