学考培训网

漳州
切换分站

咨询热线 13923776320

您所在位置: 学考培训网 > 教育资讯> 漳州IT认证> 漳州web前端> HTTPWeb服务器---HTTP整体设计框架

HTTPWeb服务器---HTTP整体设计框架

发布时间:2022-12-08

整个项目采用B/S模式(浏览器-服务器模式),通过浏览器发送的method(只要包含GET和POST两种方法),server对此进

行响应,最终通过html显示所得到的结果。

因为服务器同时处理多条连接,因此采用了多线程的结构。


HTTP是在TCP之上,它负责在发送端“生成针对目标Web服务器的HTTP请求报文”和在接收端“对对Web服务器请求的内容

进行处理”,传输功能是由TCP完成的,因此首先我们要创建建监听tcp socket


1.服务器初始化

这里创建tcp sock过程与其他socket编程一致,分别为:socket–>bind–>listen。即创建tcp socket–>绑定端口号–>监听

socket

在绑定端口号时,我们采用sockaddr_in的方式,另外为了实现端口的复用,采用了setsockopt中SO_REUSRADDR方式。


2.进行accept及多线程的建立

我们进行accept接收客户端的connect请求。


accept成功以后,我们使用pthread_create来进行创建线程,把socket托付给线程来进行操作。在线程处理的过程中,有一个

问题就是线程等待,我们为了解决这个问题,我们使用线程分离,这样使得线程可以作为孤儿进程的形式托管给1号进程,当执

行完毕以后,由1号进程来进行资源的回收。

每次收到一个请求都创建一个线程,之所以处理线程是让线程去处理请求,其中让一个线程处理请求,另一个线程可以去调

accept处理下一个请求,两者互不耽误。

另外,不使用多进程是因为创建进程成本高;I/O多路复用也可以。


3.线程处理

在整个线程处理函数中,我们对HTTP的请求进行分析。


a)获取HTTP信息

线程处理函数中最主要的工作就是进行HTTP请求的分析,获取HTTP信息,因为HTTP是一种行文本格式协议,因此我们采取

的方式是按行读取。

例如:在读取首行时,我们为了获取首行中有效信息–metnod和url.

就可以把HTTP请求的方法(GET或POST,目前只进行处理这两个),资源路径(url)和最后一个字段–HTTP 的版本信息均获得

在得到这些资源之后,我们现在要进行处理, 接下来就是考虑参数。HTTP请求经常会带一些参数,通过这些参数浏览器请求资

源。其中GET方法的资源是在url当中,POST方法的资源是在消息正文当中,这样我们也就能得到资源了。

参数形式举例:

?a=1&b=2 (均以‘?’开头,’?’后面是一对对用‘&’符号分割的键值对)

需要说明的是,我们项目的多线程HTTP服务器有三种情况:


非CGI:此时不带参数,返回主页给浏览器

GET CGI:此时参数在url后,并且按照一定的规律连接,我们需要把参数提出来交给CGI程序去进行运算

POST CGI:此时参数在消息正文当中,我们需要结合消息报头,提取参数

b)非CGI模式

我们这里先来看下非cgi方式,这种情况下,首先明白此时我们可以得到资源路径,这个资源路径其实就是根目录下的路径,

默认我们去寻找根目录下的主页。

所以我们需要给资源加上index.html

然后我们把整个index.html的信息发送给scoket。


c)GET CGI模式

对于GET CGI模式,最重要的就是解析出url中的url_path和query_string。

如果是method==GET,并且没有query_string,就认为是静态页面

如果是method==GET,且有query_string,就可以根据query_string参数内容动态计算生成页面

d)POST CGI模式

对于POST CGI模式,此时参数在消息正文当中,我们需要结合消息报头,提取参数,那么就简单了,我们只用提取出消息报头

中的content_length,(此处为了简单,只保留了content_length,其他的header内容直接就丢弃了), 然后获取到这个长度

以后,我们就可以知道向socket读取多少长度的内容了,然后读取完以后我们就可以获得到参数,同样是按照“?”和“&”的

形式进行组织的,我们取出这个内容,然后进行数据运算操作。


注意

在每次对于错误的处理时,我们都将统一返回404,还要注意的是此处只考虑短连接,而短连接的意思是每次浏览器给服务器端

发送请求之前,都是新建立一个socket进行连接,如果响应写完了,就可以关闭new_sock。但因为此处是服务器主动断开连

接,也就会进入TIME_WAIT状态,由于服务器可能短时间处理大量的连接,就会导致服务器上出现大量的TIME_WAIT.因此就

设置setsockopt REUSERADDR来进行端口复用操作