网络应用程序体系结构
现代应用程序的主流体系结构分为:客户-服务器体系结构 和 对等P2P体系结构。
客户-服务器体系结构
在该结构中,有一个总是打开的主机 称为服务器,它服务于来自许多客户主机的请求,且它具有固定的,周知的地址,我们称为IP地址。例如web应用程序(运行在网络上,以浏览器作为通用客户端的应用程序),总是打开的web服务器 服务于 来自浏览器的请求。当web服务器接受到来自客户对其对象的请求时,它会响应客户端所请求的对象。而客户之间不直接通信。
应用了该体系结构的应用程序有Web,FTP,Telnet等。
P2P体系结构
在体系结构中,应用程序在间断连接的主机对 之间直接通信,这些主机对称为对等方,大多数对等方驻留在家庭,大学和办公室。目前许多流行的,流量密集型应用都是P2P体系结构,如因特网电话(例如Skype),迅雷和IPTV等。
某些应用具有混合的体系结构,它结合了客户-服务器体系结构 和 P2P体系结构,例如 对于许多即时讯息应用而言,服务器负责跟踪用户的IP地址,而用户到用户的报文通过用户主机直接发送,而无需通过中间服务器。
套接字
当进程运行在相同的端系统上时,它们使用进程的通信机制相互通信,而在两个不同端系统的进程,是通过计算机网络交换报文来相互通信:发送进程生成报文并向网络发送,接受进程接收报文并可能将报文发送回去作为响应。
在给定的一对进程之间的通信会话中,我们将发起通信的进程称为客户,在会话开始时等待联系的进程称为服务器
进程通过一个称为套接字的软件接口 向网络发送报文和接收报文。套接字是同一台主机内应用层与运输层之间的接口,开发者可以控制套接字在应用层端的一切,但对套接字的运输层几乎没有控制权。
传输层实现了端到端的通信,而这两个端点就是套接字。
若要想一台主机上运行的进程发送分组,我们需要IP地址和端口号。
web服务器端口号为80,邮件服务器进程端口号为25.
HTTP协议
Web概述
万维网(Web)是一个由互相连接的超文本(可以显示在电脑显示器或其他电子设备的文本)组成的系统,它是一种信息共享服务,比如在网页中,当我们点击一个链接,就可以跳转到另一个网页。
万维网与因特网的联系
因特网是由上千万台设备组成的网络,使用TCP/IP协议让不同设备彼此通信。在因特网上,你可以找到许多联网的计算机,,而在万维网上,你会找到各种文件,声音,视频等信息;在因特网中 通过计算机之间的电缆进行连接,而在万维网上,是通过超文本链接进行连接。
Web页面
Web页面由对象组成,而这个对象只是一个文件,比如一个HTML文件,一个Java小程序或视频片段这样的文件。HTML基本文件通过对象的URL地址引用页面中的其他对象。URL地址由存放对象的服务器主机名 和 对象的路径名 组成,例如 http://www.someSchool.edu/someDepartment/picture.gif,其中www.someSchool.edu是主机名,/someDepartment/picture.gif是路径名。
Web对象存储于Web服务器,每个对象由URL来寻找。流行的Web服务器有Apache等。
HTTP概述
HTTP是万维网的数据通信的基础,万维网应用遵循HTTP协议,即超文本传输协议。它定义了Web客户向Web服务器请求Web页面的方式,以及服务器向客户传送Web页面的方式
用C/S结构来说明HTTP协议的作用:
- 客户:浏览器向服务器发出对页面中包含对象的HTTP请求报文,在接收到对象后展示Web对象。
- 服务器:响应客户的请求,发送对象。
结合前面的套接字的概念,我们可以进一步扩展的说明:客户向它的套接字接口发送HTTP请求报文,并从它的套接字接口接收HTTP响应报文。类似的,服务器从它的套接字接口接收HTTP响应报文,并从它的套接字接口发送HTTP请求报文。
HTTP采用的传输协议——TCP传输服务。
需要注意的是,HTTP是一个无状态协议:客户端向客户发送被请求的文件时,是不会存储关于该客户的状态信息。如果某个特定客户在短短几秒内两次请求同一对象,服务器不会因为刚刚提供服务给该对象 就不再做出反应的,它会重新发送该对象。
有状态的协议更复杂:
- 需维护状态(历史信息)
- 若客户或服务器失效,会导致状态的不一致。
非持续连接和持续连接
根据应用程序及应用程序的使用方式,客户对服务器的一系列请求可以是以规则的间隔 周期性地发出,也可以是间断地一个接一个发出。若每个请求/响应对是经过一个单独的TCP连接发送的,称为非持续连接;若所有请求/响应 经相同的TCP连接发送,称为持续连接。
对于非持续连接,需要为每一个请求的对象建立和维护一个全新的连接,由于客户和服务器都要分配TCP的缓冲区和保持TCP变量,这样会给Web服务器带来负担。同时每一个对象消耗的时间更长。
在采用持续连接的情况下,一个完整的Web页面可以用单个持续TCP连接进行传送,一般来说,若一条连接经过一定的时间间隔未被使用,HTTP服务器就关闭该连接。HTTP的默认模式是使用代流水线的持续连接。
持续连接可以省去较多的TCP建立和关闭操作,对于操作频繁,点对点的通信,且连接数不能太多的场景适用此方式;而非持续连接对服务器来说,管理较为简单,存在的连接都是有用的。它多用于Web网站的http服务,且适用于并发量大,但每个用户无需频繁操作的场景。
HTTP请求报文的组成
- 请求头。
- 请求行。
- 请求体。
(1)请求行由请求方法字段、URL字段和HTTP协议版本字段3个字段组成,它们用空格分隔。如上图的 GET /index.html HTTP/1.1。
HTTP协议的请求方法有GET、POST、HEAD、PUT、DELETE。
HEAD方法:当服务器收到使用HEAD方法的请求时,会用一个HTTP报文进行相应,但不返回请求对象。开发者通常使用HEAD方法进行调试跟踪。
PUT方法:允许用户上传对象到指定的Web服务器上指定的路径。
DELETE:允许用户或应用程序删除Web服务器上的对象。
(2)请求头由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息,典型的请求头有:
- User-Agent:产生请求的浏览器类型,上图为火狐浏览器
- Accept:客户端可识别的内容类型列表
- Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机
(3)请求体:在使用GET方法时,实体体为空;而使用POST方法时才使用到实体体,若我们用POST方法来提交表单,而实体体中包含的是表单字段中的输入值。
HTML经常使用GET方法,在请求的URL中会包含输入的数据
HTTP中Get/Post的区别
GET /test/demo_form.asp?name1=value1&name2=value2 HTTP/1.1
POST /test/demo_form.asp HTTP/1.1 Host: w3schools.com name1=value1&name2=value2
- GET 用于获取资源,而 POST 用于传输实体主体。
- 因为 URL 只支持 ASCII 码,因此 GET 的参数中如果存在中文等字符就需要先进行编码。例如
中文
会转换为%E4%B8%AD%E6%96%87
,而空格会转换为%20
。POST 参数支持标准字符集。 - GET会将参数暴露在url上,某种程度上不安全,而POST将参数放在Request body中;
- GET在url中传送的参数长度有限制,POST在Request body没有长度、数量限制;
- GET请求参数会被完整保留在浏览器历史里,而POST的参数不会被保留
- GET在浏览器中回退是无害的,回退操作实际上浏览器会从之前的缓存中拿结果。而POST会再次提交请求
-
GET和POS本质上都是TCP连接,上述区别的根本原因在于,HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。例如,(大多数)浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url。如果在GET的Request Body中偷带数据,但是不保证该数据会被处理。
此外,GET产生一个TCP数据包;POST产生两个TCP数据包(并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。)。对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
HTTP幂等性
幂等性是指 若一个方法重复执行多次,产生的效果是一样的,则这个方法就是幂等的。
场景举例
假设有一个从账户取钱的方法,即从account_id对应的账户中扣除amount数额的钱;如果扣除成功则返回true,账户余额减少amount;如果扣除失败则返回false,账户余额不变。
bool withdraw(account_id, amount);
在分布式环境中,可能会出现:withdraw()方法的请求已被服务端正确处理,但服务器端返回结果由于网络原因被弄丢了,导致客户端无法得知处理结果。若是在网页上,一些不恰当的设计可能会使用户认为上一次操作失败,然后刷新页面,导致withdraw()方法调用2次,账户多扣了1次。
针对这种问题,我们可以将withdraw()方法变成幂等的,比如添加一个create_ticket()方法。该方法获取一个服务器生成的唯一处理号tick_id,用于标识后续操作:一个tick_id表示 操作最多只会被执行1次,每次调用都返回第一次调用时的处理结果。
HTTP的幂等性介绍
此处以HTTP的GET、DELETE、PUT、POST方法来解释。
(1)GET方法:用于获取资源,不应有副作用,因此是幂等的。需要强调的是此处是指调用1次和调用N次都具有相同的副作用,而不是每次GET的结果相同,每次得到的结果可能不同,但它本身没有任何副作用。比如获取当前时间的方法。
(2)DELETE方法:删除资源,有副作用,但它应满足幂等性。调用1次和调用N次都具有相同的副作用,比如删除id为4231的帖子。调用者可多次调用或刷新页面而无需担心错误。
(3)POST方法:用于创建资源,有副作用,不满足幂等性。它所对应的URI是执行创建动作的操作者。例如:POST http://www.forum.com/articlesd的语义是在http://www.forum.com/articles下创建帖子,HTTP响应中包含帖子的创建状态和帖子的URI。而两次相同的POST请求会在服务器端创建两份资源,它们的URI不同,因此POST不满足幂等性。
(4)PUT方法:创建或更新操作。它所对应的URI是创建或更新的资源本身,有副作用,它应满足幂等性。比如:
PUT http://www.forum/articles/4231的语义是创建或更新ID为4231的帖子。对同一URI进行多次PUT的副作用和一次PUT是相同的;因此,PUT方法具有幂等性。
HTTP的POST操作不是安全的,也不是幂等的。当反复刷新页面会导致多次提交表单,发出同样的POST请求。因此后端的WebService 一定要做到幂等性,其次服务器收到POST请求并操作成功后,必须302跳转到另一个页面,这样即使用户刷新页面也不会导致重复提交。
HTTP响应报文的组成部分
- 响应行
- 响应头
- 响应体
(1)响应行通过提供一个状态码说明请求资源情况,例如:
- 200 OK:客户端请求成功。
- 400 Bad Request:客户端请求有语法错误,不能被服务器所理解。
- 401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。
- 403 Forbidden:服务器收到请求,但是拒绝提供服务。
- 404 Not Found:请求资源不存在,举个例子:输入了错误的URL。
- 500 Internal Server Error:服务器发生不可预期的错误。
- 503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)
(2)响应头为响应报文添加了一些附加信息,例如:
- Content-Type:响应正文的类型(是图片还是二进制字符串,例如HTML,JPS,JSP,JSON)
- Content-Charset:响应正文使用的编码
- Content-Language:响应正文使用的语言
HTTP状态码
通知
1xx:指示信息--表示请求已接收,继续处理
- 100 Continue-继续,请求者应当继续提出请求。服务器返回此代码表示已收到请求的第一部分,正在等待其余部分
- 101 Switching Protocols-切换协议,切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议。
成功
2XX系列响应代码表明操作成功了。
- 200 OK-成功,表示服务器成功执行了客户端所请求的动作
- 201 Created-已创建,请求成功并且服务器创建了新的资源
- 202 Accepted-已接受,服务器已接受请求,但尚未处理
- 203 Non-Authoritative Information-非授权信息,服务器已成功处理了请求,但返回的信息可能来自另一来源
- 204 No Content-无内容,服务器成功处理了请求,但没有返回任何内容。
重定向
3XX表示客户端需要做些额外工作才能得到所需要的资源。它们通常用于GET请求。他们通常告诉客户端需要向另一个URI发送GET请求,才能得到所需的表示。那个URI就包含在Location响应报头里。
- 301 Moved Permanently-永久移动:被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。对于某些使用HTTP/1.0协议的浏览器,当它们发送的POST请求得到了一个301响应的话,接下来的重定向请求将会变成GET方式。
- 302 Found-发现:临时移动,要求客户端执行临时重定向。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。
- 303 See Other-查看其它地址。请求者应当对不同的位置使用单独的GET请求来检索响应时,服务器返回此代码。
- 304 Not Modified-未修改。自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容
- 305 Use Proxy-使用。所请求的资源必须通过访问
- 307 Temporary Redirect-临时重定向。在这种情况下,请求应该与另一个URI重复,但后续的请求应仍使用原始的URI。与302相反,当重新发出原始请求时,不允许更改请求方法。例如,应该使用另一个POST请求来重复POST请求
- 308 Permanent Redirect-永久重定向。请求和所有将来的请求应该使用另一个URI重复。 307和308重复302和301的行为,但不允许HTTP方法更改。
客户端错误
4XX表明客户端出现错误。不是认证信息有问题,就是表示格式或HTTP库本身有问题。客户端需要自行改正。
- 400 Bad Request 这是一个通用的客户端错误状态,当其他4XX响应代码不适用时,就采用400。此响应代码通常用于服务器不理解请求的语法
- 401 Unauthorized-未授权,请求要求身份验证。对于需要登录的网页,服务器可能返回此响应
- 403 Forbidden-禁止 服务器拒绝请求。该响应代码常用于一个资源只允许在特定时间段内访问,或者允许特定IP地址的用户访问的情况。403暗示了所请求的资源确实存在。
- 404 Not Found-未找到。404表明服务器无法把客户端请求的URI转换为一个资源即找不到资源
- 405 Method Not Allowed-方法禁用,禁用请求中指定的方法
- 407 Proxy Authentication Required-请求要求的身份认证,与401类似,但请求者应当使用进行授权
- 408 Request Time-out,服务器等候请求时发生超时
- 409 Conflict-冲突,请求的操作会导致服务器的资源处于一种不可能或不一致的状态
- 410 Gone-已删除,如果请求的资源已永久删除,服务器就会返回此响应
服务端错误
5XX表明服务器端出现错误。一般来说,这些代码意味着服务器处于不能执行客户端请求的状态,此时客户端应稍后重试。有时,服务器能够估计客户端应在多久之后重试。并把该信息放在Retry-After响应报头里。
- 500 Internal Server Error-内部错误,服务器遇到错误,无法完成请求。对于大多数web框架,如果在执行请求处理代码时遇到了异常,它们就发送此响应代码
- 501 Not Implemented-尚未实施,服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码
- 502 Bad Gateway-错误网关,服务器作为网关或***,从上游服务器收到无效响应
- 503 Service Unavailable-服务不可用,服务器目前无法使用(由于超载或停机维护)
- 504 Gateway Time-out-网关超时,服务器作为网关或***,但是没有及时从上游服务器收到请求
- HTTP Version not supported-HTTP版本不受支持,服务器不支持请求中所用的 HTTP 协议版本
重定向和转法的区别
重定向过程:
- 客户浏览器发送http请求
- web服务器接受后发送302状态码响应及对应新的location给客户浏览器
- 客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址
- 服务器根据此请求寻找资源并发送给客户。在这里location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。
转发过程:
- 客户浏览器发送http请求
- web服务器接受此请求
- 调用内部的一个方法在容器内部完成请求处理和转发动作
- 将目标资源发送给客户;在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。
URL和URI的区别
- URI是同一资源标志符,可以唯一标识一个资源。即在某一规则下把一个资源独一无二的标识出来;
- URL是同一资源定位符,可以提供该资源的路径。它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。
- 假设所有的Html文档都有唯一的编号,记作html:xxxxx,xxxxx是一串数字,即Html文档的身份证号码,这个能唯一标识一个Html文档,那么这个号码就是一个URI;URL则通过描述是哪个主机上哪个路径上的文件来唯一确定一个资源,也就是定位的方式来实现的URI。
HTTP1.1和1.0区别
(1)长短连接
1.0默认使用短连接,即每次请求都重新建立一次连接,每一次的建立或断开都需要3次握手和4次握手的开销,开销较大;
1.1默认使用长连接:默认开启Connection:keep-alive。当一个网页打开后,传输HTTP数据的TCP连接不会关闭,可以继续使用。持续连接有流水线方式和非流水线方式,流水线方式是指客户在收到响应报文之前 可以直接发送新的请求报文;非流水线方式是指 客户端在收到前一个响应后才能发送下一个请求。
(2)错误响应码
1.1新增了24个错误状态响应码:如409表示请求的资源与资源当前状态发生冲突;410表示服务器上的某个资源被永久性删除。
(3)带宽优化
1.0存在一些浪费带宽的现象,例如客户端只需要某个对象的一部分,而服务器却把整个对象送过来;1.1在请求头引入了range头域,它允许 只请求资源的某一部分,即返回码是206.
(4)缓存处理
.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since,If-Match,If-None-Match等更多可供选择的缓存头来控制缓存策略。
(5)Host头处理
1.0认为每台服务器都绑定着唯一的IP地址,因此请求消息中的URL没有传递主机名。随着虚拟主机技术的发展,一台物理服务器上可以存在多个虚拟主机,且它们共享一个IP地址。1.1的请求消息和响应消息支持Host头域,且请求消息中如果没有Host头域会报告400错误。
HTTP 2.0和1.1区别
(1)多路复用
1.1:若干个请求排队串行单线程处理,后面的请求等待前面请求返回才能获得执行机会。一旦有某请求超时等,后续请求只能被阻塞。这种情况即线头阻塞。
2.0:同域名下所有通信在单个连接完成,而单个TCP连接相当于两个管道(一个用于服务器到客户端,一个用于客户端到服务器)。在1.x中,管道里面的数据传输是通过字节码传输,每个字节一个一个的传输。例如客户端要向服务器发送Hello、World两个单词,只能是先发送Hello再发送World,
在HTTP 2.0中可以要同时发送这两个单词,需要将数据拆成包,打上标签,比如①H ②W ①e ②o ①l ②r ①l ②l ①o ②d。等到了服务器后,服务器根据标签将两个单词分开。这里引入一个概念:二进制分帧。在二进制分帧层中,HTTP 2.0将请求和响应数据分割成帧,且它们采用二进制格式的编码。多个帧可以乱序发送,根据帧首部的标识可以重新组装。
这样并行交错的发送请求/响应,请求/响应之间互不影响,且也消除了因多个TCP连接带来的延时和内存消耗。
(2)首部压缩
HTTP 1:请求和响应都是由 状态行、请求 / 响应头部、消息主体组成,消息主体会经过gzip压缩,或者本身传输的是压缩后的二进制文件(例如图片,音频),但状态行和头部没有压缩,直接以纯文本传输。
随着Web功能越来越复杂,消耗在头部的流量越来越多,而每次传输的UserAgent、Cookie 这类不会频繁变动的内容是一种浪费。因此在HTTP 2,对这些首部采取压缩策略:
- 客户端和服务端使用 首部表来跟踪和存储 之前发送的键值对,对于已有且值没有变化的,不再通过每次的请求和响应发送;
- 首部表在HTTP 2.0的连续存续期间始终存在,由客户端和服务器共同逐渐更新。
- 每个新的首部键-值对要么被追加到当前表的末尾,要么替换表中之前的值
(3)支持服务器推送
当代网页使用了很多资源:HTML,图片,样式表,脚本等等。在HTTP 1.x中的这些资源都必须明确的请求,而服务器必须等待浏览器做的每一个请求,网站经常是空闲和未使用的。这可能是一个很慢的过程。
为了改善延时,HTTP 2.0引入server push。在浏览器明确请求之前,服务器经常知道一个页面需要附加资源,在它响应浏览器第一个请求的时候,可以开始推送这些资源。这允许服务端去完全充分地利用一个可能空闲的网络,改善页面加载时间。
比如服务端可以主动把 JS 和 CSS 文件推送给客户端,而不需要客户端解析 HTML 时再发送这些请求。
HTTP3新特性
上文提到的HTTP/2使用的多路复用,如果连接出现丢包,则整个TCP都要开始等待重传,导致后面的数据都被阻塞。这里HTTP/2的表现就不如HTTP/1了,因为HTTP/1.1是开启多个TCP连接,只会影响其中一个连接。
QUIC新特性
0-RTT
基于此问题,HTTP/3使用了基于UDP的QUIC协议,它通过使用类似TCP快速打开的技术,缓存当前会话的上下文。在下次恢复会话的时候,只需要将之前的缓存传递给服务端验证通过就可以进行传输了
TCP快速打开:通过握手开始时的SYN包中的TFO cookie来验证一个之前连接过的客户端。如果验证成功,它可以在三次握手最终的ACK包收到之前就开始发送数据
0-RTT是QUIC相比于HTTP2最大的性能优势:传输层0RTT就能建立连接;加密层0RTT就能建立加密连接。
下图左边是HTTPS的一次完全握手的建连过程,需要3RTT,会话复用则需要至少2RTT。而右图的QUIC只需0个RTT就能实现数据发送。
多路复用
与 HTTP2.0 一样,同一条 QUIC 连接上可以创建多个流 来发送多个HTTP请求。而QUIC是基于UDP的,一个连接上多个流之间没有依赖。如下图所示,虽然stream2丢失,但不影响后面跟着的stream3和stream4,不存在TCP队头阻塞。
向前纠错机制
每个数据包除了它本身的内容之外,还包括了部分其他数据包的数据,因此少量的丢包可以通过其他包的冗余数据直接组装而无需重传。向前纠错牺牲了每个数据包可以发送数据的上限,但是减少了因为丢包导致的数据重传,因为数据重传将会消耗更多的时间。
Cookie技术
HTTP协议是无状态的,服务器单从网络连接上无从知道客户身份,但很多应用需要服务器掌握客户端状态,如网上购物。因此我们引入Cookie技术。
Cookie实际上是一小段的文本信息,是服务器发送到用户浏览器并保存在本地的一小块数据。即:
Cookie原理
Cookie的流程
- 客户端访问服务器时,发送一个不带Cookie头部行的HTTP请求消息;
- 服务器发现客户端是新来的,为它创建识别码1678,并将识别码作为索引在它的后端数据库产生一个表项。在返回给客户端的响应消息中,加上Set-cookie:1678;
- 浏览器接受到后,解析出来并将数据放入自己的Cookie文件中;
- 当客户端再访问时,发送的HTTP请求消息中都会添加cookie:1678,客户端通过查询数据库得知该客户端之前来过,并对客户端做出特定动作。
Cookie作用
- 身份认证
- 购物车
- 推荐
Cookie的生存时间
- 存放在内存中:整个会话期。即浏览器关闭时就会自动清除Cookie,浏览器将Cookie保存在内存中。
- 保存在客户端的硬盘中(有过期时间):浏览器关闭的话,该Cookie 也不会被清除,下次打开浏览器访问对应网站时,这个Cookie就会自动再次发送到服务器端。
Session
Session是服务器和客户端一次会话的过程,Session 对象存储特定用户会话所需的属性及配置信息。不同于Cookie的是:Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,即Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
3.1 Session创建以及和cookie配合过程(以用户登录为例)
- 用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建创建对应的 Session ,请求返回时将此 Session 的唯一标识信息 SessionID 返回给浏览器。
- 浏览器接收到服务器返回的 SessionID 信息后,会将此信息存入到 Cookie 中,同时 Cookie 记录此 SessionID 属于哪个域名。
- 当用户第二次访问服务器的时候,请求会自动判断此域名下是否存在 Cookie 信息,如果存在自动将 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息,如果没有找到说明用户没有登录或者登录失效,如果找到 Session 证明用户已经登录可执行后面操作。
- 由于会有越来越多的用户访问服务器,因此Session也会越来越多。为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。
(1)只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session。如果尚未生成Session,也可以使用request.getSession(true)强制生成Session。
(2)Session如何传递session id?
- 采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器,但cookie可以被人为的禁止。
- 倘若浏览器中禁止了cookie:(1)把session id附加在URL路径的后面,附加的方式有两种,一种是作为URL路径的附加信息(
xxx?SessionID=123456...
。),另一种是作为查询字符串附加在URL后面。网络在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个session id。(2)以 Post 的方式提交。(3)Session和Cookie的区别
- Session工作在服务器中;Cookie工作在客户端。
- 有效期不同,Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效。
- Cookie支持跨域名访问,例如将domain属性设置为“.biaodianfu.com”,则以“.biaodianfu.com”为后缀的一切域名均能够访问该Cookie。跨域名Cookie如今被普遍用在网络中,例如Google、Baidu、Sina等。而Session则不会支持跨域名访问。Session仅在他所在的域名内有效。
- 隐私策略不同,Cookie 存储在客户端,比较容易遭到不法获取,早期有人将用户的登录名和密码存储在 Cookie 中导致信息被窃取;Session 存储在服务端,安全性相对 Cookie 要好一些。
- 存储大小不同, 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie。
(4)如何删除或使Session失效
- 从服务器角度:重新启动服务器
- 客户端角度:设置失效时间;关闭浏览器(Cookie分为内存中Cookie(也可以说是进程中Cookie)和硬盘中Cookie。大部分的Session机制都使用进程中Cookie来保存Session id的,关闭浏览器后这个进程也就自动消失了,进程中的Cookie自然就消失了,那么Session id也跟着消失了,再次连接到服务器时也就无法找到原来的Session了。)
(5)注:
- 同一浏览器同时打开多个标签,发送同一请求或不同请求,它们仍是同一session
不在同一个窗口中打开相同的浏览器时,发送请求,仍是同一个session;
使用不同的浏览器时,发送请求,即使发送相同的请求,是不同的session;
把当前某个浏览器的窗口全关闭,再打开,发起相同的请求时,就是上点说到的,是不同的session。
Web缓存/代理服务器技术
该技术可以实现在不访问服务器的前提下 满足客户端的HTTP请求。Web缓存器有自己的磁盘存储空间,该空间保存最近请求过的对象的副本。我们可以配置浏览器,使得所有的HTTP请求首先指向Web缓存器。
浏览器向缓存/代理服务器发送所有的HTTP请求流程:
- 若请求对象在缓存中,缓存返回对象
- 否则,缓存服务器向原始服务器发送HTTP请求,获取对象,然后返回给客户端并保存该对象。
发明技术的原因:
- 缩短客户请求的响应时间
- 减少机构/组织的流量。
FTP文件传输协议
和HTTP协议一样,它用来在两台计算机之间传送文件。如下图所示,用户通过一个FTP用户代理和FTP交互,用户需要提供远程主机的主机名,使本地主机的FTP客户进程建立一条到远程主机FTP服务器进程的TCP连接。然后用户接着提供用户标识和口令,作为FTP命令的一部分在该TCP连接上传送。一旦服务器向该用户授权,用户就可以将存放在本地文件系统中的文件复制到远程文件系统(反之亦然)。
FTP服务器必须在整个会话期间保留用户的状态,这也是与无状态的HTTP不同的一点。
与HTTP协议一样,它同样也是用TCP来传输文件,不同的是,FTP通过两个TCP连接来传送一个文件(一个用的传输命令,一个用于数据传输):
- 控制连接:用于在两主机之间传输控制信息,如用户标识,口令,改变远程目录的命令及“存放”,“获取”文件的命令
- 数据连接:传送一个文件数据。该链接是非持续的,即每一次文件传输都需要建立新的连接。
根据数据连接是否是服务器主动建立,FTP有主动和被动模式:
- 主动模式(PORT命令):FTP客户端通过向FTP服务器发送PORT命令,告诉服务器该客户端用于传输数据的临时端口号。当需要传送数据时,服务器通过TCP端口号20与客户端的临时端口建立数据传输通道,完成数据传输。在建立数据连接的过程中,由服务器主动发起连接。
- 缺点:FTP服务器企图与客户端的高位随机端口建立连接,而这个端口很有可能被客户端的防火墙阻塞掉。
- 被动模式(PASV方式):FTP客户端通过向FTP服务器发送PASV命令,告诉服务器进入被动方式。服务器选择临时端口号并告知客户端当需要传送数据时,客户端主动与服务器的临时端口号建立数据传输通道,完成数据传输。在整个过程中,服务器总是被动接收客户端的数据连接。
被动模式会导致服务器端的安全性减弱,因为开放了过多的端口号。
Email应用
Email应用的构成及发送流程
每个接收方在其中的邮件服务器上有一个邮箱,该邮箱 管理和维护发送给接收方的报文。一个典型的邮件发送过程是:从发送方的用户代理开始,传输到发送方的邮件服务器,再传输到接受方的邮件服务器,然后在此处 分发到接收方的邮箱中。当接收方要在它的邮箱中读取该报文时,包含它邮箱的邮件服务器通过用户名和口令来鉴别其身份。若发送方的服务器 不能将邮件交付给 接收方的服务器,接收方的邮件服务器会在一个报文队列中保持该报文并在以后尝试再次发送。若几条后仍不能成功,服务器会删除该报文 并以电子邮件的方式通知 发送方。
为什么要建立邮件服务器,而不是直接将邮件发送到对方?
原因之一是对方的邮件客户端不能保证7*24在线的,倘若对方没有接入Internet,我们就无法发送邮件。
而邮件服务器是一直确保开着,这样我们就可以任意时刻发送邮件给对方。
SMTP
SMTP是因特网电子邮件中主要的应用层协议,它使用TCP可靠传输服务。每台邮件服务器既运行SMTP的客户端,也运行SMTP的服务器端:当一个邮件服务器向其他邮件服务器发送邮件时,它就表现为SMTP的客户;当邮件服务器从其他邮件服务器接收邮件时,它就表现为SMTP的服务器。
SMTP限制所有邮件报文的体部分只能采用7位ASCII码表示。
SMTP应用实例
(1)客户SMTP(运行在发送邮件服务器上)在25端口建立一个到服务器SMTP(运行在接收邮件服务器)的TCP连接。若服务器没有开机,客户会在稍后继续尝试连接。
(2)一旦连接成功,服务器和客户执行某些应用层的握手,你可以想象成SMTP的客户和服务器在传输信息前的相互介绍。在该阶段,SMTP客户会 指示发送方的邮件地址 和接收方的邮件地址。
(3)相互介绍完后,客户发送报文,SMTP依赖TCP的可靠数据传输 无差错的将邮件投递到接收服务器。如果客户有另外的报文要发送,则需要在相同的TCP连接上 重复该处理。否则 它会指示TCP关闭连接。
SMTP与HTTP的对比
- HTTP主要是一个拉协议:Web服务器上装载着信息,而用户使用HTTP从服务器拉取信息;而SMTP基本是一个推协议:发送邮件服务器 把文件推向接受邮寄服务器。
- SMTP要求每个报文使用7比特ASCII码格式,若某保温包含了非7比特ASCII码格式(如图形文件等),则报文必须按照7比特ASCII码格式 进行编码;而HTTP不受此限制。
- 对于一个既包含文本 又包含图形(或其他媒体类型)的文档,HTTP会把每个对象封装到自己的HTTP响应报文;而SMTP把所有报文对象放到一个报文中。
Email消息格式
由于消息体只能是ASCII字符,倘若消息体是非ASCII文本类型(比如中文)。这时我们就需要多媒体扩展MIME
多媒体扩展MIME
它通过在邮件头部增加额外的行以声明MIME的内容类型。互联网邮件扩充 MIME 可以发送二进制文件。MIME 并没有改动或者取代 SMTP,而是增加邮件主体的结构,定义了非 ASCII 码的编码规则。
邮件访问协议
由于SMTP是一个推协议,而取报文是一个拉操作。因此我们需要 从服务器获取邮件的 邮件访问协议
POP3
当用户代理打开一个邮件服务器 端口110上的TCP连接后,POP3就开始工作了。POP3按照3个阶段进行工作:
- 特许阶段:用户代理(客户)发送用户名和口令 以鉴别用户。
- 事务处理阶段:用户代理取回报文,同时还能对报文做删除标记,取消删除标记,以及获取邮件的统计信息;
- 更新阶段:它出现在用户发出quit命令之后,目的是去取消该POP3会话。这时,该邮件服务器删除那些被标记为删除的报文。
以往POP3使用的是下载并删除方式,一旦邮件发送到PC机或MA C上,邮件服务器上的邮件将会被删除。这可能会造成问题:接收方可能会从不同的及其访问它的邮件报文,若开始是从公司PC收取邮件,那么在其他机器将不能再收取该邮件。
不过目前的POP3邮件服务器大都可以“只下载邮件,服务器端并不删除”,也就是改进的POP3协议。
IMAP
IMAP服务器把每个报文与一个文件夹联系起来:当报文第一次到达服务器时,它与收件人的INBOX文件夹相关联,收件人能把邮件移到一个新的,用户创建的文件夹中。IMAP协议为用户提供了创建文件夹 和 将邮件从一个文件夹移到另一个文件夹的命令。IMAP还提供了远程文件夹中查询邮件的命令。
IMAP维护了IMAP会话的用户状态信息,例如 文件夹的名字以及哪些报文 与哪些文件夹相关联。
IMAP还允许用户代理 去获取报文组件。例如,一个用户代理可以只读取一个报文的报文首部,或只是一个多部份MIME报文的一部分。当用户代理和其他邮件服务器之间使用低带宽连接。当使用低宽带连接时,用户可能不希望取回邮箱中的所有邮件。
基于Web的电子邮件
如今有不少的用户使用他们的Web浏览器收发电子邮件。在这种服务,用户代理是普通的浏览器,用户和他远程邮箱之间的通信 是通过HTTP进行。而发件人发送的邮件报文是从其浏览器到他的邮件服务器,使用的也是HTTP。
DNS
DNS概念
互联网上有许许多多的主机设备组成网络,而这些主机都需要唯一的标识符(IP地址)。IP地址本身都是数字,不利于人类识别使用,所以我们日常上网标识主机的都是域名。
域名,是由一串用点分隔的字符组成的互联网上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位。域名可以说是一个IP地址的代称,目的是为了便于记忆后者。例如,
wikipedia.org
是一个域名,和IP地址208.80.152.2
相对应。
人类喜欢这种便于记忆的域名,而路由器则喜欢这种定长,有层次结果的IP地址,因此我们需要解决域名和IP地址之间的映射问题。
域名解析系统DNS
它是多层命名服务器构成的分布式数据库,即服务器分布在全世界,而不是集中在一个地方。它提供了主机名和 IP 地址之间相互转换的服务
同时,它也是个应用层协议,在它之上有软件完成名字的解析。他运行在UDP之上,使用53端口。
DNS通常由其他应用层协议(包括HTTP,SMTP,FTP)使用,将用户提供的主机名解析为IP地址,比如说:当用户输入一个URL:www.someSchool/index.html页面时:
- 同一台主机上运行着DNS应用的客户端;
- 浏览器从URL抽取出主机名:www.someSchool.edu,将其传给DNS应用客户端;
- DNS应用的客户端向DNS服务器发送一个包含主机名的请求;
- DNS应用的客户端收到 包含对应IP地址的回答报文;
- 浏览器向位于该IP地址80端口的HTTP服务器进程发起TCP连接。
DNS服务器的分层结构
DNS服务器分为:根DNS服务器,顶级域(TLD)服务器和权威服务器。
举例来说:假设主机cis.poly.edu想知道主机gaia.cs.umass.edu的IP地址:
- 主机cis.poly.edu 向它的本地DNS服务器dns.poly.edu发送一个DNS查询报文.
- 本地DNS服务器将该报文转发到根DNS服务器,该DNS服务器 注意到其edu前缀,并向本地DNS服务器返回负责edu的TLD的IP地址列表。
- 本地DNS服务器向这些TLD服务器之一发送查询报文。该TLD服务器注意到umass.edu前缀,并以权威DNS服务器的IP地址作为响应,该权威DNS服务器是dns.umass.edu。
- 本地DNS服务器直接向dns.umass.edu发送查询报文。dns.umass.edu以gaia.cs.umass.edu的IP地址作为响应。
本地域名解析服务器
- 它不严格属于层次体系
- 每个互联网服务供应商(ISP)都有一个本地域名服务器
- 当主机进行DNS查询时,它作为代理,将查询转法给层级式域名解析服务器系统
DNS查询方式
1.迭代查询
2.递归查询
DNS记录缓存
为了增加访问效率,DNS系统有域名缓存机制:当访问过某个网站并得到其IP后,会将其域名和IP缓存下来,下一次访问的时候,就不需要再请求域名服务器获取IP,直接使用缓存中的IP,提高了响应的速度。当然缓存是有有效时间的,当过了有效时间后,再次请求网站,还是需要先请求域名解析。
DNS反向解析
DNS服务器里面有两个区域,即“正向查找区域”和“反向查找区域”,正向查找区域就是域名解析,反向查找区域即是IP反向解析,它的作用是通过查询IP地址的PTR记录来得到该IP地址指向的域名,当然,要成功得到域名就必需要有该IP地址的PTR记录。PTR记录是邮件交换记录的一种,邮件交换记录中有A记录和PTR记录,A记录解析名字到地址,而PTR记录解析地址到名字。地址是指一个客户端的IP地址,名字是指一个客户的完全合格域名。通过对PTR记录的查询,达到反查的目的。IP反向解析主要应用到邮件服务器中来阻拦垃圾邮件,特别是在国外。多数垃圾邮件发送者使用动态分配或者没有注册域名的IP地址来发送垃圾邮件,以逃避追踪,使用了域名反向解析后,就可以大大降低垃圾邮件的数量。
用 xxx@name.com 这个邮箱给我的邮箱 123@163.com 发了一封信。163邮件服务器接到这封信会查看这封信的信头文件,这封信的信头文件会显示这封信是由哪个IP地址发出来的。然后根据这个IP地址进行反向解析,如果反向解析到这个IP所对应的域名是name.com 那么就接受这封邮件,如果反向解析发现这个IP没有对应到name.com,那么就拒绝这封邮件。
HTTPS
概述
SSL(安全套接层)和它的继承者:传输层安全TLS 是一种为网络通信提供安全和数据完整性的安全协议。TLS与SSL在传输层对网络连接进行加密。
HTTPS协议可以理解为HTTP下加入SSL/TLS协议层。
HTTP存在的问题
如下图所示,HTTP请求过程中,客户端与服务器之间没有任何身份确认,数据全部明文传输。因此黑客可以截获发给服务器的信息,也可以冒充服务器,返回任意信息给客户端而不被客户端察觉。
为防止上述现象的发送,人们便对传输的信息加密.
HTTP向HTTPS演化的过程
对称加密
双方拥有相同的密钥,且只有一个密钥作为私钥。但是:
- 客户端,服务器数量庞大,双方维护大量的密钥而耗费的成本很高
- 每个客户端,服务器的安全级别不高,密钥容易泄露
非对称密钥
加密和解密使用的是不同的密钥:一把公开的密钥,另一把作为私钥。客户端用公钥对请求内容加密,服务器使用私钥对内容解密。但也存在缺点:
- 公钥是公开的,即黑客也会有公钥,第4步若被黑客截获,也可用公钥解密。
- 公钥和私钥成对出现
- 公开的密钥叫公钥,只有自己知道的叫私钥
- 用公钥加密的数据只有对应的私钥可以解密
- 用私钥加密的数据只有对应的公钥可以解密
对称密钥与非对称密钥的结合
- 在第三步中,客户端说:“我们后续的回话采用对称加密,这是对称加密的算法和对称密钥”,并用公钥将这段话加密,传给服务器。
- 服务器接收到后,用私钥解密,提取出相关内容后,并返回回应(该回应用对称密钥加密)。
- 后续双方的信息传输通过对称加密的方式
遇到的问题:
- 客户端如何获得公钥
- 如何确定服务器不是黑客
获取公钥和确认服务器身份
通过SSL证书来获取公钥(防止黑客冒充服务器,发送假的公钥给客户端)。SSL证书中包含:
-
证书的发布机构CA
-
证书的有效期
-
公钥
-
证书所有者
-
签名
客户端在收到SSL证书后,会对其真伪进行校验。以浏览器为例说明如下:
(1)首先浏览器读取证书中的证书所有者、有效期等信息进行一一校验
(2)浏览器开始查找操作系统中已内置的受信任的证书发布机构CA,与服务器发来的证书中的颁发者CA比对,用于校验证书是否为合法机构颁发
(3)如果找不到,浏览器就会报错,说明服务器发来的证书是不可信任的。
(4)如果找到,那么浏览器就会从操作系统中取出 颁发者CA 的公钥,然后对服务器发来的证书里面的签名进行解密
(5)浏览器使用相同的hash算法计算出服务器发来的证书的hash值,将这个计算的hash值与证书中签名做对比
(6)对比结果一致,则证明服务器发来的证书合法,没有被冒充
(7)此时浏览器就可以读取证书中的公钥,用于后续加密了
缺点
- 因为需要进行加密解密等过程,因此速度会更慢;
- 需要支付证书授权的高额费用。
HTTPS加密,解密过程
(1)客户端请求HTTPS网站,然后连接到服务器的443端口。该端口是HTTPS的默认端口。
(2)采用HTTPS的服务器必须要有数字CA证书,证书是需要申请,由专门的数字证书认证机构审核后颁发的电子证书。办法证书的同时会有私钥和公钥。私钥由服务端保存,不可泄漏;公钥则是附带在证书的信息中,可以公开。证书本身附带一个证书电子签名,签名用来验证证书的完整性和真实性,防止证书被篡改。
(3)服务器响应客户端请求,将证书传递给客户端,证书包含公钥,证书颁发机构,公司信息等。
在chrome浏览器点击地址栏左边的锁标志,在点击证书即可看到证书详细信息。
(4)客户端解析证书并对其进行验证。若证书没有问题,客户端会从服务器证书中取出公钥A,并生成一个随机码KEY,使用公钥对其加密;若证书不是可信机构颁发 或证书中的域名与实际域名不一致,或证书已过期,就会向访问者显示警告。
(5)客户端把加密的随机码KEY发送给服务器,作为之后对称加密的密钥。
(6)服务器在收到KEY后,使用私钥对其解密,最后客户端和服务器建立了安全连接,之后使用对称加密进行通信。
SSL与TLS
SSL
位于可靠的面向连接的网络层协议和应用层协议之间的一种协议层,该协议由 SSL记录协议和SSL握手协议 组成。
该协议提供的服务:
- 认证用户和服务器,确保数据发送到正确的客户机和服务器;
- 加密数据,防止数据中途被窃取;
- 维护数据完整性,确保数据在传输过程中不被改变。
SSL协议的工作流程:
服务器认证阶段:
(1)客户端向服务器发送开始信息“Hello”,以便开始一个新的会话连接。
(2)服务器根据客户的信息来确定是否需要生成新的主密钥,如需要 则服务器在响应客户的“Hello”信息中放入生成主密钥所需的信息;
(3)客户根据收到的响应信息,生成一个主密钥,并用服务器的公钥将其加密,传给服务器;
(4)服务器恢复该主密钥,并返回给客户一个用主密钥认证的信息,以此让客户认证服务器;
客户认证阶段:
此前 已完成客户对服务器的认证,此阶段主要完成对客户的认证。
(1)经认证的服务器发送一个提问给客户,客户返回数字签名和其公钥,从而向服务器提供认证。
TLS
安全传输层协议TLS用于在两个通信应用程序之间提供保密性和数据完整性。该协议由TLS记录协议(位于某个可靠传输协议之上,如TCP) 和 TLS握手协议 组成。
TLS记录协议用于封装各种高层协议,它允许服务器和客户机在应用程序协议传输和接收其第一个数据字节前 彼此相互认证,协商加密算法和加密密钥。
TLS是SSL 3.0的后续版本,它们支持的加密算法不同,因此两者不能互操作。TLS和SSL的差别有:
(1)版本号:TLS记录格式和SSL记录格式相同,但版本号的值不同:TLS1.0使用的版本号为SSLv3.1。
(2)报文鉴别码:SSL3.0和TLS的MAC算法和MAC计算的范围不同,TLS使用了RFC-2104定义的HMAC算法,在该算法填充字节和密钥之间采用的是异或运算,而SSL的算法与其类似,但填充字节和密钥之间采用的是连接运算。不过两者的安全程度是相同的。
(3)伪随机函数:TLS使用了PRF的伪随机函数来讲密钥扩展成数据块,这是更安全的方式。
(4)报警代码:TLS支持几乎所有的SSLv3.0报警代码,且还补充定义了很多报警代码,如解密失败(decryption_failed)、记录溢出(record_overflow)、未知CA(unknown_ca)、拒绝访问(access_denied)等。
相比于SSL 3.0,TLS提供了:
- 更安全的MAC算法
- 更严密的警报
- “灰色区域”规范的更明确的定义
参考博客
- https://blog.nowcoder.net/n/aae672c111664b029b49d88dd22af492
- https://blog.csdn.net/meiyalei/article/details/2129120
- https://blog.csdn.net/jackxinxu2100/article/details/8145318
- https://zhuanlan.zhihu.com/p/27395037
- https://songlee24.github.io/2015/05/03/public-key-and-private-key/
- http://www.ityouknow.com/it/2019/05/11/cookie-session.html
- https://zhuanlan.zhihu.com/p/34109504
- https://www.zhihu.com/question/21950864
- https://developer.51cto.com/art/202001/609520.html
- https://blog.fundebug.com/2019/03/07/understand-http2-and-http3/ :HTTP各版本特性