目录
- 一、概念
- 基础概念
- 响应码
- 请求和响应报文的格式
- http无连接
我叫张贺,贪财好色。一名合格的LINUX运维工程师,专注于LINUX的学习和研究,曾负责某中型企业的网站运维工作,爱好佛学和跑步。
个人博客:传送阵
笔者微信:zhanghe15069028807
,非诚勿扰。
一、概念
基础概念
OSI七层参考模型与TCP协议栈的区别 :OSI的七层参考模型只是参考模型,只是纸上谈兵罢了,而TCP/IP是以OSI七层模式为基础演化而来的实际使用的模型,是实战派。OSI七层参考模式的上三层是资源子网,而下四层为通信子网。
主机与主机之间的通信:在linux的内核当中,下四层的通信功能都是在内核当中实现,主机与主机之间的通信依靠内核与内核就可以完成,也就是直接在内核空间就可以完成,根本用不上用户空间的参与,事实上,的确有此种程序,这是一种结构。
还有另一种结构,把应用程序建立在用户空间,用户空间的程序想要完成通信的话就必须依靠内核空间当中通信子网,也就是说用户空间的程序想要完成通信的话就必须依靠内核的通信子网。
套接字:套接字是为了实现进程与进程之意的通信的一种机制,主要目的在于允许同一主机或者不同主机的不同进程之意进行通信。套接字其实有两种类型。一般来讲,一在个主机上,一个完整套接字由特定的IP+特定的端口组成,想要实现这种套接字需要内核当中的tcp/ip协议栈参与封装报文,这只是一般来讲,而事实上,套接字是分为两种类型的,第一种就是IP+端口的方式,这种类型的套接字主要是为了完成主机之间的通信,IP用来标识不同的主机,而端口用来标识不同的服务。此外还有一种套接字,这种套接字叫做unix sock,它存在的目的是为了完成同一个主机上进程之间的通信,比如说可以把一个程序的输出定向到一个文件当中,然后下一个程序去这个文件当中取出数据,这其实是通过文件系统实现的,而文件系统又是内核实现的,这种基于文件系统或者文件的套接字就被称为unix sock.
raw套接字:不基于tcp也不基于udp而是应用程序自行控制维护报文的传输,这种奇怪的应用程序是存在的,其实这就意味着有的应用程序可以绕过传输层,但是无论如此也绕不过网络层。 这样的话套接字就有了三种。
主机与主机之间传输文件的简略过程:这个文件被用户空间送入内核空间后,首先是由网络层进行封装,每一个数据包的总大小大不能超过16位,也就是65535个字节(B),而这65535个字节是包含IP首部,而IP的首部最少是20个字节,最大是60个字节,所以一个IP数据包除去首部之后要传输的数据大小范围为:65475B-----65515B之间,也就是说一个IP数据包要传输的文件大小范围在0.65M左右。
这一个数据包到达下一层数据链路层的时候还要切片,链路层数据的最大传输单元是大于等于46字节小于等于1500个字节,加上帧头与帧尾固定的18个字节,也就是一个数据帧的大小范围是大于等于64个字节小于等于1518个字节,也就是一个数据帧的大小介于0.064KB到1.518KB之间。
等到到达目的主机之后根据标识标志片偏移合并起来最终提交给用户空间的应用层。
TCP与UDP:tcp的全称是transmisson control protocol传输控制协议,也称做是面向连接的协议。udp的全称是user datagram protocol 用户数据报协议,无连接,也称做是不可靠的连接。它们两个区别就是tcp在建立连接时需要首先建立虚连接(三四)。
物理层与数据链路层实际是由网络硬件设备与其对应的驱动程序组成,比如一个网卡加上这个网卡的驱动程序就只可以实现物理层与链路层的功能,而驱动实际上又工作在内核空间当中,由内核直接调用,TCP/IP协议栈也在内核当中 ,所以我们说通信子网(下4层)实际上全部都是内核当中的。
跨主机的通信: 互联网上绝大多数的跨主机通信都是c/s架构的。所谓的服务端的用户空间的服务程序在启动是会向内核注册申请一个套接字,这种套接字通常是特定的IP+特定端口,当服务程序向内核申请注册以后,内核就有一个“职责”,内核要时刻等待来访问此套接字的数据,一旦识别数据包访问的是此套接的话,内核就会根据其信息知道到底是哪个进程注册了此套接字,进而会把此数据包提交给用户空间的应用程序。
那么内核是怎样识别数据包访问的是哪个进程呢?一个主机上有那多的进程,套接字有那么多,内核是怎样办到的呢?TCP/IP协议栈就位于内核当中,当内核在解封装的时候就会识别出来,通过网络层识别访问的主机,通过传输层识别访问的是哪个进程。
主动与被动:服务端因为是要提供服务的,相当于医院当中医生坐诊,要等待用户访问,不能主动出去拉客,那么这就是被动,而被动需要一个具体的地址等待客户的请求,所以服务器要申请侦听的套接字都是比较固定的。客户端则不同,客户端不需要等待别人访问,所以客户端也就没有必要申请一个固定的套接字使用,只要选择一个没有被使用的端口即可。
客户端的IP加上端口、服务端的IP加上端口,这四种元素就可以标识一个完整的连接,这四种元素只要变化其一种,就可以标识一种不同的连接。
应用层协议:假设一个ftp的客户端要与smtp的服务端进行通信可以成功吗?smtp可以识别ftp的请求吗?当然是不可以的,这些程序在设计的时候都是遵守一定的规范来设计编写,能识别的请求是特定的请求,其实也就是说只能识别按照某一种特定规范编写的请求,那么这种规范是什么?其实这种规范就叫做应用层协议。举个例子httpd程序是根据http协议设计编写的,那么它能识别的客户端的请求也只能是根据http协议开发出的客户端请求,如果一个ftp的客户端去访问httpd进程的话,httpd是不会识别的,因为httpd服务只能根据根据http协议开发的程序发出的请求。
应用层的协议是特定的,而传输层的协议是通用的 。内核当中的通信子网只是负责传输的,就像通用的软件,各种应用都可以进行调用,因为它只负责通信,所以它不管上层的应用是否能够识别信息,能够识别请求信息取决应用层协议。
何为http? hypertest transport protocol超文本传输协议。那么什么样的文本就是超文本呢?遵守html格式编写的语言就是超文本。什么是html?hypertest mark language超文本标记语言。
URI和URL : URL(uniform resource locator)是统一资源定位符,而URI(uniform resorce identifier)是统一资源标识符,URI存在的意就是为了标识资源的唯一性。URL是URI的子集,因为URL只是实现了URI规定的一部分功能,一个完整的URL通过是这样的:
http://www.magedu.com/image/logo.jpg #完整的URL示例
Ø http:// 是方案、我们通过将其理解成为协议,其实就是通过哪个方式获取资源,通过ftp也可以呀!
Ø www是主机而不是域名
Ø magedu.com这是是域名
Ø /image/logo.jpg指的是访问资源的路径,这是绝对路径。
客户端和服务端:http的客户端叫做browser(浏览器),服务端就是一个遵守http协议的应用程序。那么客户端是怎样访问服务端的呢?浏览器它会提供一个地址栏让用户输入URL来获取资源,常用的http的浏览器有两种类型是GUI和CLI。
html :上面的标记语言是为让客户端的浏览器方便显示的,具体的效果,比如文本颜色和文本大小的微调需要css的参与才可以,使用html和css开发的网页都是静态的网页。此外还有动态网页,所谓的动态网页就是不仅有html和css组成,此外还有程序脚本。网页程序脚本分为两种,一种是在客户端执行,一种是在服务端执行,现在最常见的就是在服务器执行的脚本,因为如果在客户端执行脚本的话很不安全。当一个客户端访问一个提供动态网页时的服务器时,服务器会在本地把脚本执行一下,然后通过html标记以后把结果返回给客户端。
前端语言:前端语言就是指开发网页时编写脚本的语言,最常用的前端语言有php,asp.net,jsp这是三种最常见的,php用于中小型网站的开发,而大型网站要通过jsp开发,当然只要是遵守CGI(common geteway interface通用网关接口协议)的语言都可以开发网页,比如:C,C++,python等其实都可以可以的,比如C也可以开发网页,而且开发出来的网页跑的贼快!普通的语言需要解释器,而C不用解释器可以直接运行,但是为什么不用C呢?因为C的主要还是用来开发操作系统的,开发网页并不是太好用,开发和维护的成本相较于专门开发网页脚本的PHP要大的多。
值得一提的是:flash动画与动态网站是没有一分钱的关系的。
一个网页文件可能是有多个对象存在的。还是以上一个html为例子,客户端通过browser请求此html文件,当把此文件请求下来之后,客户端的浏览器会发现还要加载一个图片于是还要再次向服务器发送请求,把此图片再请求下来,总而言之,当我们请求一个网页时并不是只请求一次就够的,图片与html是两个文件,并不是一个文件。网页当中的对象可以是服务器本地的资源,比如图片,而且还可以是别的服务器或者别的网站的图片,只要客户端的浏览器能够请求到都可以被显示。明文这一点非常的重要。举个例子,淘宝网页上的图上非常之多,难道这些图片都存在放服务器的本地之下吗?并不是这样的,这些图片可能分散到多台服务器,这样很多用户进行请求的时候就不会对单台服务器产生太大的压力,而谷歌和百度的界面并不是太花,因为要保证用户的体验尽可能的快,明白此理论对以后的调优意义重大。
超文本是通过http协议传输的文本,http是超文本传输协议,并不是超图片传输协议,那么网页当中的图片是通过怎样的方式传递到客户端的呢?当然是通过超链接链过去的,那么这个图片是通过什么协议加载到客户端的本地的呢?图片是二进制编码格式,而http协议只能传输超文本,总不能把图片的二进制当成是文本通过http传输给客户端吧!这样肯定不行,因为到了客户端那边是不能够还原的,客户端会看到一堆的乱码。怎样办呢?在解开这个谜团之前我们要先了解了一下http的版本。
http的版本:http于1991研制成功之后发展至今有三个版本。
l 0.9版本,此版本为第一版,仅仅支持html文档,真心是不能传输图片。
l 1.0版本,此版本为第二版,不仅支持html文档,还支持多媒体数据的传输,当然,不仅是增加此一项功能,这里并不多讲,http发展到这一个版本就其实就可以传输图片了。那么它是怎样实现的呢?说是http多媒体的实现不得不提的是smtp(简单的邮件传输协议),引协议早先也只能传输文件,后来为了扩展功能加入了传输多媒体的机制:MIME:multpurpose internet mail extension,此中机制通过base64的编码,实现了将二进制数据编码当成文本发送,并能够让接收方还原回来的格式,而http1.0的版本也借用此机制。在1.0的版本上,还引入了缓存的机制,能够保持连接(keep-alive),使得用户体验更加顺畅。
l 1.1版本在1.0基础上再次完善,更精确的缓存控制,更多的请求方法,原生支持持久连接。成为至今使用最为广泛的版本。
事务:客户端对http服务的一次请求加上http服务的一次响应就可以标识一个http完整的连接,这个过程就是http的事务.
方法:客户端对http的请求不仅一种,有时我们需要获取页面(get),有时我们需要向http提交页面(put),有的时候仅需要知道有没有这个报文希望http服务端响应一下就好,不用把页面的数据传送回来(head),有时需要提交表单(pust),删除页面(delete),事实上常用的方法有8种,以上的5种比较常见.
常见的方法
GET:客户端向服务器请求获取资源,需要服务器回复响应报文。
HEAD:与GET相似,仅要求服务器端返回首部信息即可以,不需要将内容返回,用于探测
POST:支持HTML表单的提交,比如当用户注册的时候,用户注册的信息会通过表单的形式发送到服务器,由服务器存储到某个位置(例如发给处理程序做处理)
PUT:也是提交,post偏向于提交创建,而PUT偏向于提交之后更新。
DELETE:请求删除URL指向的资源
OPTIONS:探测服务器对某资源所支持的请求方法
TRACE:跟踪请求要经过的防火墙、代理或网关
响应码
200:成功
302:临时跳转
301:永久跳转
403:没有权限
404:页面不存在
500:服务器内部错误,通过是程序导致
502:请求不到后端的资源
503:服务器不可用
504:请求后端资源
1XX
1XX:1开头的状态码都是信息性状态码,没什么具体的含义,也很少见到
2XX
2XX:以2开头有一个必须要记住200,200代表成功状态,201代表提交成功
3XX
3XX:重定向状态码:
301:moved parmanently永久重定向,在服务器响应时使用首部”location:URL”指定资源现在所处的位置,比如客户端把URL指向服务器上的一软链接,服务器给客户端响应时会在首部告诉客户端真正的文件在什么地方,让客户端再去连接。
302:found,临时的重定向,在服务器响应时使用首部”location:URL”指定资源现在所处的位置,看下来与永久重定向没有什么区别?事实上,区别还是很大的,一个永久重定向告诉客户端真实文件所在之处后,客户端就可以直接使用真正的位置,而临时重定向则不然,客户端每次访问时也要先访问这个临时重定向,每一次事务都要要如此,因为它是临时,保不齐什么时候又指向别的位置了呢。
总结:永久的重定向可以留给后面的连接用,而临时的连接不能留给后面的连接使用
304:not modified没有改变,当用户使用浏览器访问一个网站之后,会在本地有一个缓存,等到下次再访问的时候,服务器端直接响应一个304告诉客户端网页没有改变,这样的话可以加快用户的体验。
4XX
4XX:客户端的错误
403:forbidden请求被服务器拒绝,可能没有权限
404:not found 服务器没有找到请求的URL
405:不允许使用此方法请求相应的URL
5XX
5XX:服务器错误
500:internal server error 服务器内部错误
502:bad gateway代理服务器或者网关路由出了问题,也可以从上游收到了一条不能用的响应。
503:service unavailable服务器此时无法提供服务,但将来可以使用
请求和响应报文的格式
请求和响应:整体来讲http的报文只有两种格式,一是请求,二是响应.无论是请求报文还是响应报文都是有特殊格式的.
请求报文格式:request
#<方法><资源><版本>,因不同的版本特性不同,所以必须注明版本(http)信息.
是用来标记属性的,每个请求或者响应报文可包含任意个首部;每个首部都有首部名称,后面跟一个冒号,而后跟上一个可选空格,接着是一个值。
这个空白行是必须要有的
#报文的主体,包含要请求的内容,请求报文的实体有可能为空,请求就应该为空,因为本来就不传输什么。
资源可以是本地上的,也可以是别的服务器或者站点上面的.版本号的格式是http/版本号,如http/1.1
响应报文格式:response
#<版本><状态><原因短语>,比如1.1 200 ok
#这指的是一个类:首部,其实首部就是指的是名称+值的格式,可以有多个
#这个空白行是必须要有的
#报文的主体,包含要回应的内容,如果是响应是一个文件的话,那么这个文件就包含在entity-body里面。
http无连接
本小节概括:本小节主要介绍http的无连接机制,为什么要加速?怎样加速?
http是无连接的,何为无连接?即完成一次事务就必须断开,就是收到一个请求然后做出一个回应之后就要断开,这种机制其实是比较浪费资源的,效率低下,下文有一个例子,请仔细的体会:
当客户端访问www.baidu.com的时候,除去DNS不谈,第一步就是通过URL事务获取一个网页(一去一回),这一步仅仅是为获得网页的内容而已,仅这一个事务就经历了三次握手和四次挥手,然后客户端的浏览器通过读取获得的html文件得知还要获得10个图片,然后还要经历10个三次握手和四次挥手才能完整的显示出百度的页面.如果淘宝的网页的话可能有上百个图片需要获得,所以效率非常的低下.
因为无连接的http效率非常的低下,所以需要加速,其实加速的目的很简单,就是为了让用户获得更好的体验,获得网页的速度能够加快,那么怎样才能加速http呢?两种方法,并行和保持连接.
所谓并行,就是客户端一次发多个请求,而服务器一次回应多个请求,假如当一个浏览器读取html文件后发现还要获得10个图片,客户端会在建立三次握手之后 ,一次性发出5个请求,然后服务器也同时响应这个5个请求,客户端等到5个图片获得之后再四次挥手,这样话10张图片仅需要两次三次握手和四次挥手,当然这是建立在所有的图片都得在同一个IP下,如果不在同一个IP下,一般来讲都会在一个主机上,一般不会有那种10张图片分布10台服务器的情况,如果10张图片都分布在10个服务器上的话并行的机制就无法完成,就只能一个事务一事物的连接,毕竟一次连接只能用于一个IP.必须要提的是并行的机制是发生在获得主页面的前提下,任何加速方式都是在获得主网页的前提下实现的,而获得主页面的过程,客户端和服务器必须老老实实的完成一个事务.
所谓保持连接就非常好理解了,当获得主要页面之后,三次握手获得一个图片之后并不进行四次挥手,而是一直保持着连接,来完成下面9张图片的传输,等到9张图片都传输完毕之后再进行四次挥手,这种方式的效率是很高的,但并不是完全没有缺点,假如一个服务器只能同时接收5000个连接,但是同时进来了10000个请求,那么5000连接就要被拒之门外,而已经连入的5000个请求因为要请求的资源很多,很长时间都不断开的话,门外的5000个连接就没有机会,我们深入想一想就会知道这种情况并不好,用户体验很差,用户连接了几次发现很验证连上可能以后都不会这个网站了,上次考试报名的时候就遇到过这种情况 .所以为了保证服务质量和用户体验,所以http又有断开的机制,下面就来讲一下http的断开机制.
断开机制:保持连接,三次握手以后不断开,完成之后终的断开,并不是全都是好处,比如说当用户访问淘宝的时候刚打开网页却恰好有事出去了,对于服务器来并不知道,服务器仍然以为有人在访问它,一个用户无所谓,假如是成千上万台都这样做呢?有的攻击方式就是这种原理,所以服务器有一种机制来防止这种情况的发生,那就是断开机制。
其实断开机制是我们买车时候的保险是相似的,一台新车在3年或者10万公里内可以保修,那么这个3年和10万公里是什么意思?是这样:
Ø 如果3年不到但是已经超过了10万公里,对不起,不保修!,因为违反了公里限制!
Ø 如果3年到了但是没有超过10万公里,对不起,不保修!因为这里违反了时间限制!
Ø 只有在3年以内而且没有跑够10万公里,才可以保修。
断开的方式:超时或者限制最大资源数
超时:工程师规定连接到达10秒,就必须重新断开
限制最大资源数:一旦链接后的请求资源达到100个就必须断开,一秒到上限就一秒断开,1分钟到达上限就一分钟断开。
这两种规则是同时生效的,无论违反哪一个就会断开重新连接,这种机制就是为了弥补保持连接的,让那些被“拒之门外”的连接也有很大的机会。
客户端在建立连接之后到达10秒上限,断开,重新连接。
客户端在建立连接之后请求了100个资源,断开,重新连接