整个项目采用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,因此采取如图方式
HTTPWeb服务器---HTTP整体设计框架
就可以把HTTP请求的方法(GET或POST,目前只进行处理这两个),资源路径(url)和最后一个字段–HTTP 的版本信息均获得
在得到这些资源之后,我们现在要进行处理, 接下来就是考虑参数。HTTP请求经常会带一些参数,通过这些参数浏览器请求资源。
其中GET方法的资源是在url当中,POST方法的资源是在消息正文当中,这样我们也就能得到资源了。
参数形式举例:
?a=1&b=2 (均以‘?’开头,’?’后面是一对对用‘&’符号分割的键值对)
需要说明的是,我们项目的多线程HTTP服务器有三种情况:

  1. 非CGI:此时不带参数,返回主页给浏览器
  2. GET CGI:此时参数在url后,并且按照一定的规律连接,我们需要把参数提出来交给CGI程序去进行运算
  3. 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参数内容动态计算生成页面
HTTPWeb服务器---HTTP整体设计框架

d)POST CGI模式

对于POST CGI模式,此时参数在消息正文当中,我们需要结合消息报头,提取参数,那么就简单了,我们只用提取出消息报头中的content_length,(此处为了简单,只保留了content_length,其他的header内容直接就丢弃了), 然后获取到这个长度以后,我们就可以知道向socket读取多少长度的内容了,然后读取完以后我们就可以获得到参数,同样是按照“?”和“&”的形式进行组织的,我们取出这个内容,然后进行数据运算操作。

注意

在每次对于错误的处理时,我们都将统一返回404,还要注意的是此处只考虑短连接,而短连接的意思是每次浏览器给服务器端发送请求之前,都是新建立一个socket进行连接,如果响应写完了,就可以关闭new_sock。但因为此处是服务器主动断开连接,也就会进入TIME_WAIT状态,由于服务器可能短时间处理大量的连接,就会导致服务器上出现大量的TIME_WAIT.因此就设置setsockopt REUSERADDR来进行端口复用操作

相关文章:

  • 2021-12-16
  • 2022-12-23
  • 2022-03-01
  • 2022-02-07
  • 2021-08-09
  • 2021-10-06
  • 2018-05-31
猜你喜欢
  • 2021-11-04
  • 2021-10-28
  • 2021-04-10
  • 2021-07-01
  • 2021-05-16
  • 2021-06-10
  • 2021-12-06
相关资源
相似解决方案