优化版本的HTTP服务器项目

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wyn126/article/details/82700745

项目介绍

开发语言/环境:C语言,linux Centos6.5
项目分析:
1、基于 HTTP/1.1 版本的协议,支持长链接
2、采用 Reactor的时间处理模式和半同步/半反应堆的并发模式
3、使用了半同步/反应堆线程池,来提高创建销毁的时间
4、使用了I/O 复用中的 epoll模型
5、使用了时间堆来管理定时任务,使用 webbench来测试它在一分钟的连接数


项目的相关背景知识

背景:http协议被广泛使用,从移动端,pc端浏览器,http协议无疑是打开互联网应用窗口的重要协议,http在网络应用 层中的地位不可撼动,是能准确区分前后台的重要协议。
目标:对http协议的理论学习,从零开始完成web服务器开发,坐拥下三层协议,从技术到应用,让网络难点无处遁形
描述:采用C/S模型,编写支持中小型应用的http,并结合mysql,理解常见互联网应用行为,做完该项目,你可以从技术 上完全理解从你上网开始,到关闭浏览器的所有操作中的技术细节
技术特点:网络编程(TCP/IP协议, socket流式套接字,http协议) 多线程技术 cgi技术 shell脚本 mysql C api技术 使用多路转接技术进行升级
实现具体细节:
这里写图片描述

项目实现的大致流程

画流程图

具体实现细节
1、GET方法和POST方法
GET方法和POST方法的区别:
知道GET方法和POST方法,GET方法和POST理解的比较多一些,因为比较常用。PUT方法,HEAD方法,DELETE方法,POTIONS等方法是否提供是不一定的,因为要考虑到服务器的安全性问题
(1)GET和POST在传参形式上有所不同,GET方法通过url传参,post方法通过请求正文传参
(2)以带参的GET方法和POST方式传参时,必须以cji方式进行处理
GET方法只有在传参时要以cgi方式运行,而POST方法全部都以cgi方式运行
(3)GET方法传参时,会把信息回显到浏览器上,POST方法传参时,会将参数放在正文里
(4) 在url上面传参,参数长度受限制;在正文上面传参,参数不受限制;
GET方法传参,将参数放在query_string的数组里;POST方法传参,用的是while循环
2、cookie和session的区别(cookie和session是根据无状态提出来的)
cookie,把用户的信息保存在用户本地,session把用户的信息保存在用户的服务器端,保存的是session ID
3、 状态码
HTTP状态吗是用以表示服务器HTTP响应状态的3位数字代码。通过状态码就可以知道服务器是否正确的处理了请求。
响应状态码为200,表示成功响应,文本描述为OK。响应状态码有很多种。
1XX:接收的请求正在处理
2XX:请求正常处理完毕
3XX:需要进行附加操作以完成请求 ,重定向
4XX:服务器无法处理请求
5XX:服务器请求出错
eg:
(1)200 ok:客户端发来的http请求,被正确处理了
(2)204 No Content:表明请求结果被正确处理了,但是响应信息中没有响应正文。
(3)206 Partial Content:该状态码表示客户端对服务器进行了范围请求,而且服务器成功的执行了这部分GET请求,响应报文中包含由 Content-Range指定的实体内容范围:类似于视频加载
(4)301 Moved Permanently:永久性重定向 该状态码表示请求的资源已经被分配了新的URI,以后应使用新的URI
(5)302 Found 临时性重定向:目标资源被分配了新的URL,希望用户本次使用新的URI进行访问
(6)307 Temporary Redirect 临时重定向(与302有着相同含义,但307会遵照浏览器标准,不会从POST变成GET。)
302与307的区别:这两个其实差不多,只不过这两个在标准上通常会有一些不同,在重定向之后,发起二次请求时,会把GET方法转成POST方法,但是302/307怎么做跟浏览器有很大关系
(7)400 Bad Request 该状态码表明请求报文中存在语法错误,需要修改请求内容重新发送。
(8)403 Forbidden:该状态码表明浏览器所请求的资源被服务器拒绝了。
(9)404 Not Found:服务器上没有请求的资源。
(10) 500 Internal Server Error:表明服务器端在执行的时候发生了错误。
(11)Server Unavailable : 该状态码表明服务器目前处于超负载或正在进行停机维护状态。
项目流程:
首先创建一个监听套接字,获得新链接,然后创建线程来处理处理套接字,handler_request函数来处理链接,
首先获得第一行,然后进行行分析,获得请求的方法,判断方法。GET/POST正常,并且cgi=1,其他的话就将头部清楚状态码设置为404
GET方法带参为cji模式;
用stat判断资源是否存在,若不存在,清除头部,若存在,且是目录,就将首页拼接上;存在且不是目录,判断是否具有可执行权限,如果有,就将cgi设置为1
如果不以cgi方式运行,就执行echo_www
math_cgi:被http执行,
cgi其实就是用http执行一个程序
创建套接字的方法:用startup函数创建一个监听套接字,其中startup函数中包含了创建套接字的基本步骤,下去需要好好体会
创建线程:pthread_create(),线程处理函数包含了对行的处理请求
对HTTP请求的处理:按行进行处理,遇到\n,\r\n,\r都要进行换行处理,里面使用了一个窥探函数,获得第一行之后,需要获得请求的方法和url
判断请求的方法为GET方法和POST方法:GET方法和POST方法只要传参了就要以cgi方法处理,POST方法,必须要以cji方式运行,GET是常规请求没有参数,不需要cgi运行
如何判断GET方法带参数:url中如果有?,说明带参数,?左边是资源,右边是参数
处理首页:一般首页名字叫做index.html,首页内容在w3cschool中找一个,判断最后一个字符是否是/,如果是,就拼上首页 strcat
判断资源是否存在:
int stat(const char *path, struct stat *buf);//stat,可以获取文件属性信息,path表示请求的资源,buf表示资源的属性
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */ //权限
nlink_t st_nlink; /* number of hard links */ //硬链接
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */ //文件大小
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
如果请求的资源是一个目录,就给每一个目录下面也创建一个首页index.html,将首页拼上
如果请求的资源是一个二进制程序,就将此二进制程序在服务器上跑完,然后将结果返回客户端
如果对方的服务器请求的是一个二进制可执行程序,就将此二进制程序在服务器上跑完,跑的这种方式就叫做cgi
检测是否是目录或者文件,stat中已经给出判断方法
The following POSIX macros are defined to check the file type using the st_mode field:

       S_ISREG(m)  is it a regular file?

       S_ISDIR(m)  directory?                        是否是目录

       S_ISCHR(m)  character device?

       S_ISBLK(m)  block device?

       S_ISFIFO(m) FIFO (named pipe)?

       S_ISLNK(m)  symbolic link?  (Not in POSIX.1-1996.)

       S_ISSOCK(m) socket?  (Not in POSIX.1-1996.)

//查看可执行权限
_IFIFO 0010000 FIFO
S_ISUID 0004000 set-user-ID bit
S_ISGID 0002000 set-group-ID bit (see below)
S_ISVTX 0001000 sticky bit (see below)
S_IRWXU 00700 mask for file owner permissions
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IRWXG 00070 mask for group permission
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 mask for permissions for others (not in group)
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission
如果三者任意一个拥有权限,就将cji设置为1
如果是cgi:以cgi方式进行处理
处理非cgi:
如果不是cgi(资源找到了,不是目录,没有可执行权限,不是cgi):就将资源响应回去,用echo_www进行响应
响应时构建:不能直接返回,而是首先构建状态行,响应报头,空行,正文
以上都构建好之后使用sendfile函数高效发送
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count); //将文件一个文件拷贝到另一个文件,此函数速度快,直接从内核拷贝,效率高
图片不能具有可执行权限,否则就要按cgi方式运行
处理cgi
exe_cgi()
GET:直接清掉报头
POST:要一直读,读到空行,空行部分后面才是正文,正文后面时参数;如果正文多读或者少读都会遇到黏包问题
怎么读:先将报头中所有的字段全部清除掉,从报头中提取Content-Length字段,然后下次连读n个字符
linux下怎么执行一个指定路径下 的可执行程序:进程的程序替换,exec系列函数
path标识了要执行的程序,目前是由一个线程完成的,这样是不行的,执行可执行程序时要进行程>
序替换,如果单进成的话,会替换web服务器的代码,所以需要调用fork创建子进程,在进行程序替换
父进程如何获取子进程:进程间通信
环境变量、重定向、创建父子进程,进程间通信、进程程序替换,
//环境变量会被子进程继承,环境变量不会因程序替换被替换掉
忽略的问题:最容易忽略的两个问题:请求没有处理完,就开始相应;忽略掉空行
数据库相关问题
连接数据库: 切换root用户 service mysqld start
如何判断数据库是否启动:netstat -nltp
mysql -uroot -p //mysql相当于客户端
service mysqld start //mysqld想当于服务器
sshd //相当于服务器
ssh //相当于客户端
用cgi连接数据库:
comm.c comm.h //连接数据库/断开数据库
insert_cgi.c //向数据库中插入数据
创建的数据库名为class_23,
通过浏览器提交数据到insert_cgi,inset_cgi将数据插入到后台的库当中
请求正文的处理
换行符:/n /r/n /r
/n:换行符
/r:两种可能
wwwroot:图片,网页,,,,存放的是网页中的资源
HTTP是在TCP网络协议栈的下三层的最顶层,下三层已经帮我们处理了所有的细节,我们只需要对发过来的数据进行文本分析,按行为基本单位进行分析,
cji:是为了处理数据,数据就是url中的参数
cji与非cji:没有数据时,为非cji
http项目分为三个大部分:
http请求:对请求过程中的请求行进行分析处理,确定url,确定要访问的资源,并确定资源是否存在,可以访问的情况下,将资源返回回去
返回去的资源并不简单的将网页返回回去,而是要构建一个http的响应报头,响应报头包括状态行,响应报头,空行,正文,只有请求完处理完才能给出响应
项目缺点:
(1)单进程多线程服务器,每次只能处理一个客户的请求,当客户量增多时,服务器的处理能力是有限度的;(多线程的优缺点http都有)
(2)功能缺失,仅支持GET方法和POST方法,Web服务器上面资源太少
(3)访问量增多会导致服务器压力变大,导致IO效率降低,对外服务降低
https://blog.csdn.net/qq_33951180/article/details/70239745

猜你喜欢

转载自blog.csdn.net/wyn126/article/details/82700745
今日推荐