您的位置:首页 > 理论基础 > 计算机网络

网络基础 — 基于HTTP协议实现小型的web服务器

2018-02-25 22:54 691 查看

基于HTTP协议实现小型的web服务器

HTTP是通过TCP实现的可靠的网络传输.下面是一个完整的HTTP过渡到TCP实现客户端与服务器的交互:1.当客户端执行网络请求的时候,会从URL地址

中解析出URL的主机名,并将主机地址转换成IP.2.从URL解析出服务器的所用端口号3.客户端用TCP连接服务器4.连接成功后,获取输出流,并将数

据以报文的形式传递给服务器.5.当服务器接受到数据之后,进行判断和解析码,并回送一条响应报文.6.客户端从输入流中获取报文,并解析.7.最

后关闭网络的连接

常见HTTP请求服务器的方式:

1.GET请求

作用:获取服务器的某个资源,或者说是告诉服务器,我想查询的信息.

特点:明文传输(直接将传送给服务器的数据写在URL上).

常用:跳转到另一个网站,网站名就是GET传输,然后向服务器请求获取该网站.

2.POST请求

作用:向服务器传递数据,一般用来提交HTML表单时使用,服务器处理这些数据.

特点:表单上传(写入的数据,不显示在URL上)

常用:注册用户名,密码.传送给服务器处理.

3.PUT请求

作用:向服务器写入资源,在服务器创建一个文本,然后将Client传输数据给service.不过一个是写在

URL上,一个是写在form表单上. 然后servie端根据这些上传的数据进行处理.

4.DELETE请求

作用:从服务器中删除资源.(无法保证是否被删除,HTTP规范允许不通知客户端拒绝该请求)

5.HEAD请求

作用:让Service只返回报文的头部. client端根据报文的头部,能够判断(数据域的信息,判断该报文是否存在数据等)

6.OPTION请求

作用:询问服务器支持哪些方法(比如POST,GET,OPTION方法)

HTTP协议的主要特点:

1.支持客户/服务器模式

2.简单快捷:客户向服务器发送请求服务时,只需要传送请求方法和路径,请求方法常用的有GET,POST,DELETE,PUT,HEAD.OPTION.

每种方法规定了客户与服务器联系的类型的不同,由于HTTP协议简单,使得HTTP服务器的规模小,因此通信速度很快.

3.灵活:HTTP允许传输任意类型的数据对象,正在传输的类型由content-Type加以标记.

4.无连接:无连接的含义是限制每次链接只处理一个请求,服务器处理完客户的请求,并收到客户的应答后,既断开连接,采

用这种方式可以节省传输时间,请求应答机制就会断开.

5.无状态:HTTP协议是无状态协议,无状态是指协议对于事物处理没有记忆能力

这里我想补充一点东西,平日里我们在登陆了一个网页的时候,短时间内重新打开这个网页的时候就会发现自动登陆了,但是HTTP应该是无链接的

啊.这里其实是为了让用户有更好的上网体验做出的优化,你的客户端本地通常会有一个cookie文件,他保存的是你的基本信息,当你第一次访问一

个需要登录的网站时,其实是将你的cookie发送了过去,然后服务器提取出有用的信息进行登录并且针对客户端短时间内生产一个session id. 用

来标识唯一的一个用户,然后你的session id被写入你的cookie文件中,下次当你访问网页的时候直接在你的cookie当中识别出session id进行登

录. 看起来很方便,但是它对用户信息安全是有隐患的,当你通过网页登录qq时,然后呢,你被一些不可描述的钓鱼网站吸引进去了,你点击了这

个网站,这个时候你的本地cookie文件发送到该网站服务器当中! 但是由于你刚刚登陆了qq,所以你的用户名和密码都在cookie文件当中,这个时

候你就会被别人盗取你的qq号,这是一个很简单的例子! 所以网上尽量不要乱点什么不可描述的网站.

关于URL,既同一资源定位符,每个网页都对应一个URL地址,具有全球唯一性. 它包含的信息之处文件的位置以及浏览器应该如何处理它,一个完

整的URL包括协议类型,主机类型,路径和文件名.

http协议的URL格式: http://host[:port][abs_path]  => 协议://主机域名(ip地址)[端口号][资源路径]

我们的GET方法使用的是带参数的URL,既传递的参数会使用?连接在资源路径的后边; POST方法使用的是不带参数的URL,它的参数是通过http请求

正文传递给服务器的. 下图是关于HTTP的请求和响应模式:



响应报头中的状态码和状态码描述,举个例子,当请求的资源不存在的时,会收到"404 NotFound"的页面,404就是状态码,"NotFound"就是状态码

描述,既请求的文件不存在.  现在HTTP的概念差不多说完了.  那我们开始搭建我们的服务器吧. 


HTTP服务器的实现思路

1.面向链接:http协议是基于TCP通信协议,因此实现web服务器的第一步至少要能实现两个主机不同进程之间的TCP通信,并且需要解决高并发问题

所以这里推荐使用多线程服务器来构建,每次创建出来一个新线程出来的时候将线程分离,然后让这个新线程去处理这个请求.

2.分析出请求行:当服务器收到请求后,首先你需要知道的是HTTP服务器版本和请求方法,web服务器是要支持cgi的,但请求方法不同可能cgi也不同

,我们服务器比较简单所以只处理GET和POST方法)

3.判断cgi模式:如果方法为GET方法不带参那么非cgi模式,如果为GET方法并且带参,或者为POST方法那么为cgi模式.

4.响应客户端:这个时候我们已经知道了方法以及是否为cgi模式,然后开始读取URL,这里有一个细节非cig模式 请求参数会跟在URL当中,如果cgi

模式的话,参数在消息正文中,然后我们读取到路径,判断路径当中资源是否存在,如果存在判断这个资源是一个目录,普通文件还是一个可执行程序

这里分情况如果是cgi模式,直接进入cgi内部运行;只要是POST方法就需要支持cgi,直接进入cgi函数内部运行.

如果是非cgi模式时一定是GET方法并且没有参数,此时进入echo_www()函数内部即可,该函数会将所请求的资源以html的格式返回给浏览器.

接下来是解释运行cgi模式,首先服务器要从浏览器读取参数,然后创建出来一个子进程去执行cgi部分的可执行资源,父进程通过环境变量的方式

传递给子进程,子进程运行完成之后呢,将结果交给父进程,父进程再将数据输出给浏览器. 所以父进程在这个例子当中就向是一个中介,只进行

参数和结果的转交实际上并不会执行任何资源,因此将子进程的输入输出文件描述符重定向,就可以让子进程直接与浏览器"联系".

父进程做的事情

1.创建两个管道,并关闭相应的文件描述符 

2.POST方法:继续读取数据,直到读完POST的参数部分GET方法:直接从子进程读取结果

3.将数据和方法全部交给子进程后等待子进程的结果

子进程做的事情

1.关闭管道适当的文件描述符

2.对标准输入输出进行重定向

3.通过环境变量传递参数

4.进行exec程序替换

下图帮助我们理解cgi模式运行过程:



这里就是这个项目的主要思想,我们需要做的就是就是以上说到的,接下来使用代码将他们实现即可. 在编写代码当中我遇到了相当多的问题:

1.图片加载不出来: 因为我使用的是虚拟机,然后从windows将图片拖进来,让图片这个文件拥有了可执行权限,这里我还有及时发现,所以每次

程序运行的过程中加载不出来图片,以为图片拥有可执行权限后,本来应该是使用GET方法直接将图片以html形式返回给浏览器,但是这里走了cgi

的方法,所以出现了错误 我们应该让图片文件去除掉可执行权限.

2.关闭防火墙 打开桥接模式 可以让你在外部浏览器测试.   这是网络编程最开始就应该做的! 一定要提前准备好.

3.执行POST方法的时候因为没有进行drop_header操作,读取参数错误,导致结果错误.  POST方法的参数在有效载荷头部存储.

4.能够显示图片,但是显示不完整(原因:echo_www中,期望读取一行信息的line值太小,不能存下一个图片)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: