计算机网络(三)—— 应用层

应用层(HTTP)

1. ISO七层模型中表示层和会话层功能是什么?
  • 表示层:图像、视频编码解,数据加密。

  • 会话层:建立会话,如session认证、断点续传。

2. 会话层、表示层、应用层
  • 数据传输基本单位为报文;

  • 包含的主要协议:FTP(文件传送协议)、Telnet(远程登录协议)、DNS(域名解析协议)、SMTP(邮件传送协议),POP3协议(邮局协议),HTTP协议(Hyper Text Transfer Protocol)。

DNS协议

  • DNS是域名系统(DomainNameSystem)的缩写,该系统用于命名组织到域层次结构中的计算机和网络服务,可以简单地理解为将URL转换为IP地址。域名是由圆点分开一串单词或缩写组成的,每一个域名都对应一个惟一的IP地址,在Internet上域名与IP地址之间是一一对应的,DNS就是进行域名解析的服务器。DNS命名用于Internet等TCP/IP网络中,通过用户友好的名称查找计算机和服务。

NAT协议

  • NAT网络地址转换(Network Address Translation)属接入广域网(WAN)技术,是一种将私有(本地?保留)地址转化为合法IP地址的转换技术,它被广泛应用于各种类型Internet接入方式和各种类型的网络中。原因很简单,NAT不仅完美地解决了lP地址不足的问题,而且还能够有效地避免来自网络外部的攻击,隐藏并保护网络内部的计算机。

DHCP协议

  • DHCP动态主机设置协议(Dynamic Host Configuration Protocol)是一个局域网的网络协议,使用UDP协议工作,主要有两个用途:给内部网络或网络服务供应商自动分配IP地址,给用户或者内部网络管理员作为对所有计算机作中央管理的手段。

HTTP协议

  • HTTP协议工作在应用层,端口号是80。HTTP协议被用于网络中两台计算机间的通信,相比于TCP/IP这些底层协议,HTTP协议更像是高层标记型语言,浏览器根据从服务器得到的HTTP响应体中分别得到报文头,响应头和信息体(HTML正文等),之后将HTML文件解析并呈现在浏览器上。同样,我们在浏览器地址栏输入网址之后,浏览器相当于用户代理帮助我们组织好报文头,请求头和信息体(可选),之后通过网络发送到服务器,,服务器根据请求的内容准备数据。所以如果想要完全弄明白HTTP协议,你需要写一个浏览器 + 一个Web服务器,一侧来生成请求信息,一侧生成响应信息。

  • 从网络分层模型来看,HTTP工作在应用层,其在传输层由TCP协议为其提供服务。所以可以猜到,HTTP请求前,客户机和服务器之间一定已经通过三次握手建立起连接,其中套接字中服务器一侧的端口号为HTTP周知端口80。在请求和传输数据时也是有讲究的,通常一个页面上不只有文本数据,有时会内嵌很多图片,这时候有两种选择可以考虑。
    一种是对每一个文件都建立一个TCP连接,传送完数据后立马断开,通过多次这样的操作获取引用的所有数据,但是这样一个页面的打开需要建立多次连接,效率会低很多。
    另一种是对于有多个资源的页面,传送完一个数据后不立即断开连接,在同一次连接下多次传输数据直至传完,但这种情况有可能会长时间占用服务器资源,降低吞吐率。
    上述两种模式分别是HTTP 1.0和HTTP 1.1版本的默认方式
    ,具体是什么含义会在后面详细解释。

HTTP工作流程

一次完整的HTTP请求事务包含以下四个环节:

  • 建立起客户机和服务器连接。

  • 建立连接后,客户机发送一个请求给服务器。

  • 服务器收到请求给予响应信息。

  • 客户端浏览器将返回的内容解析并呈现,断开连接。

HTTP协议结构

请求报文

对于HTTP请求报文我们可以通过以下两种方式比较直观的看到:一是在浏览器调试模式下(F12)看请求响应信息,二是通过wireshark或者tcpdump抓包实现。通过前者看到的数据更加清晰直观,通过后者抓到的数据更真实。但无论是用哪种方式查看,得到的请求报文主题体信息都是相同的,对于请求报文,主要包含以下四个部分,每一行数据必须通过"\r\n"分割,这里可以理解为行末标识符。

1. 请求报文
  1. 请求报文头(只有一行)

    结构:method uri version

  • method

    HTTP的请求方法,一共有9中,但GET和POST占了99%以上的使用频次。GET表示向特定资源发起请求,当然也能提交部分数据,不过提交的数据以明文方式出现在URL中。POST通常用于向指定资源提交数据进行处理,提交的数据被包含在请求体中,相对而言比较安全些。

  • uri(统一资源标识符(Uniform Resource Identifier,或URI))用来指代请求的文件,≠URL。

  • version

    HTTP协议的版本,该字段有HTTP/1.0和HTTP/1.1两种。

  1. 请求头(多行)

    在HTTP/1.1中,请求头除了Host都是可选的。包含的头五花八门,这里只介绍部分。

  • Host:指定请求资源的主机和端口号。端口号默认80。

  • Connection:值为keep-alive和close。keep-alive使客户端到服务器的连接持续有效,不需要每次重连,此功能为HTTP/1.1预设功能。

  • Accept:浏览器可接收的MIME类型。假设为text/html表示接收服务器回发的数据类型为text/html,如果服务器无法返回这种类型,返回406错误。

  • Cache-control:缓存控制,Public内容可以被任何缓存所缓存,Private内容只能被缓存到私有缓存,non-cache指所有内容都不会被缓存。

  • Cookie:将存储在本地的Cookie值发送给服务器,实现无状态的HTTP协议的会话跟踪。

  • Content-Length:请求消息正文长度。

    另有User-Agent、Accept-Encoding、Accept-Language、Accept-Charset、Content-Type等请求头这里不一一罗列。由此可见,请求报文是告知服务器请求的内容,而请求头是为了提供服务器一些关于客户机浏览器的基本信息,包括编码、是否缓存等。

  1. 空行(一行)

  2. 可选消息体(多行)

2 响应报文

响应报文是服务器对请求资源的响应,通过上面提到的方式同样可以看到,同样地,数据也是以"\r\n"来分割。

  1. 报文头(一行)

    结构:version status_code status_message

  • version

    描述所遵循的HTTP版本。

  • status_code

    状态码,指明对请求处理的状态,常见的如下。

    • 200:成功。

    • 302:内容已经移动。

    • 400:请求不能被服务器理解。

    • 403:无权访问该文件。

    • 404:不能找到请求文件。

    • 500:服务器内部错误。

    • 501:服务器不支持请求的方法。

    • 505:服务器不支持请求的版本。

    1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码。
    2xx (成功) 表示成功处理了请求的状态代码。
    3xx (重定向) 表示要完成请求,需要进一步操作。通常,这些状态代码用来重定向。
    4xx(请求错误) 这些状态代码表示请求可能出错,妨碍了服务器的处理。
    5xx(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错。

  • status_message

    显示和状态码等价英文描述。

  1. 响应头(多行)

    这里只罗列部分。

  • Date:表示信息发送的时间。

  • Server:Web服务器用来处理请求的软件信息。

  • Content-Encoding:Web服务器表明了自己用什么压缩方法压缩对象。

  • Content-Length:服务器告知浏览器自己响应的对象长度。

  • Content-Type:告知浏览器响应对象类型。

  1. 空行(一行)

  2. 信息体(多行)

    实际有效数据,通常是HTML格式的文件,该文件被浏览器获取到之后解析呈现在浏览器中。

3.HTTP 协议包括哪些请求?
  • GET:请求读取由URL所标志的信息。

  • POST:给服务器添加信息(如注释)。

  • PUT:在给定的URL下存储一个文档。

  • DELETE:删除给定的URL所标志的资源。

4. HTTP 中,POST 与 GET 的区别

1)Get是从服务器上获取数据,Post是向服务器传送数据。

2)Get是把参数数据队列加到提交表单的Action属性所指向的URL中,值和表单内各个字段一一对应,在URL中可以看到。

3)Get传送的数据量小,不能大于2KB;Post传送的数据量较大,一般被默认为不受限制。

4)根据HTTP规范,GET用于信息获取,而且应该是安全的和幂等的。
I. 所谓 安全的 意味着该操作用于获取信息而非修改信息。换句话说,GET请求一般不应产生副作用。就是说,它仅仅是获取资源信息,就像数据库查询一样,不会修改,增加数据,
不会影响资源的状态。
II. 幂等 的意味着对同一URL的多个请求应该返回同样的结果(这里其实不应该说是结果……)。说白了就是,同一个请求,发送一次和发送N次效果是一样的!

5. HTTP的幂等性

这里主要以HTTP GET、DELETE、PUT、POST四种方法为主进行语义和幂等性的介绍。

6. 如何防范 POST 重复提交
  • HTTP POST 操作既不是安全的,也不是幂等的(至少在HTTP规范里没有保证)。当我们因为反复刷新浏览器导致多次提交表单,多次发出同样的POST请求,导致远端服务器重复创建出了资源。

  • 所以,对于电商应用来说,第一,对应的后端 WebService 一定要做到幂等性,第二,服务器端收到 POST 请求,在操作成功后必须302跳转到另外一个页面,这样即使用户刷新页面,也不会重复提交表单。

7. HTTP 与 HTTPS
  • HTTP(HyperText Transfer Protocol:超文本传输协议)是一种用于分布式、协作式和超媒体信息系统的应用层协议。简单来说就是一种发布和接收 HTML 页面的方法,
    被用于在 Web 浏览器和网站服务器之间传递信息。HTTP 默认工作在 TCP 协议 80 端口,用户访问网站 http:// 打头的都是标准 HTTP 服务。HTTP 协议以明文方式发送内容,
    不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。

  • HTTPS(Hypertext Transfer Protocol Secure:超文本传输安全协议)是一种透过计算机网络进行安全通信的传输协议。HTTPS 经由 HTTP 进行通信,但利用 SSL/TLS 来加密数据包。
    HTTPS 开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。HTTPS 默认工作在 TCP 协议443端口。

8. HTTP 与 HTTPS 区别
  • HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好。

  • 使用 HTTPS 协议需要到 CA(Certificate Authority,数字证书认证机构) 申请证书,一般免费证书较少,因而需要一定费用。证书颁发机构如:Symantec、Comodo、GoDaddy 和 GlobalSign 等。

  • HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,
    所以一共是 12 个包。

  • http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。

  • HTTPS 其实就是建构在 SSL/TLS(安全套接层/安全传输层协议) 之上的 HTTP 协议,所以, HTTPS 比 HTTP 要更耗费服务器资源。

9. HTTPS 的工作原理
  • 我们都知道 HTTPS 能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用 HTTPS 协议。

    • 客户端发起 HTTPS 请求
      这个没什么好说的,就是用户在浏览器里输入一个 https 网址,然后连接到 server 的 443 端口。

    • 服务端的配置

      采用 HTTPS 协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请,区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面(startssl 就是个不错的选择,有 1 年的免费服务)。这套证书其实就是一对公钥和私钥,如果对公钥和私钥不太理解,可以想象成一把钥匙和一个锁头,只是全世界只有你一个人有这把钥匙,你可以把锁头给别人,别人可以用这个锁把重要的东西锁起来,然后发给你,因为只有你一个人有这把钥匙,所以只有你才能看到被这把锁锁起来的东西。

    • 传送证书

      这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等等。

    • 客户端解析证书

      这部分工作是有客户端的TLS(安全传输层协议)来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随机值,然后用证书对该随机值进行加密,就好像上面说的,把随机值用锁头锁起来,这样除非有钥匙,不然看不到被锁住的内容。

    • 传送加密信息

      这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。

    • 服务段解密信息

      服务端用私钥解密后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密,所谓对称加密就是,将信息和私钥通过某种算法混合在一起,这样除非知道私钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全。

    • 传输加密后的信息

      这部分信息是服务段用私钥加密后的信息,可以在客户端被还原。

    • 客户端解密信息

      客户端用之前生成的私钥解密服务段传过来的信息,于是获取了解密后的内容,整个过程第三方即使监听到了数据,也束手无策。

10. HTTP1.0 与 HTTP1.1的区别
  • HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理

    • HTTP 1.0规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求。

    • HTTP 1.1则支持持久连接Persistent Connection, 并且默认使用persistent connection. 在同一个tcp的连接中可以传送多个HTTP请求和响应. 多个请求和响应可以重叠,多个请求和响应可以同时进行. 更加多的请求头和响应头(比如HTTP1.0没有host的字段).

      • 在HTTP 1.0时的会话方式:
        1. 建立连接
        2. 发出请求信息
        3. 回送响应信息
        4. 关掉连接
    • HTTP 1.1的持续连接,也需要增加新的请求头来帮助实现,例如,Connection请求头的值为Keep-Alive时,客户端通知服务器返回本次请求结果后保持连接;
      Connection请求头的值为close时,客户端通知服务器返回本次请求结果后关闭连接。HTTP 1.1还提供了与身份认证、状态管理和Cache缓存等机制相关的请求头和响应头。

    • 请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。例如:一个包含有许多图像的网页文件的多个请求和应答可以在一个连接中传输,但每个单独的网页文件的请求和应答仍然需要使用各自的连接。 HTTP 1.1还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容。

  • HTTP 1.1增加host字段

    • 在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。

    • HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。此外,服务器应该接受以绝对路径标记的资源请求。

  • 100(Continue) Status(节约带宽)

    • HTTP/1.1加入了一个新的状态码100(Continue)。客户端事先发送一个只带头域的请求,如果服务器因为权限拒绝了请求,就回送响应码401(Unauthorized);
      如果服务器接收此请求就回送响应码100,客户端就可以继续发送带实体的完整请求了。100 (Continue) 状态代码的使用,允许客户端在发request消息body之前先用request header试探一下server,看server要不要接收request body,再决定要不要发request body。
  • HTTP/1.1中引入了Chunked transfer-coding来解决上面这个问题,发送方将消息分割成若干个任意大小的数据块,每个数据块在发送时都会附上块的长度,最后用一个零长度的块作为消息结束的标志。这种方法允许发送方只缓冲消息的一个片段,避免缓冲整个消息带来的过载。

  • HTTP/1.1在1.0的基础上加入了一些cache的新特性,当缓存对象的Age超过Expire时变为stale对象,cache不需要直接抛弃stale对象,而是与源服务器进行重新激活(revalidation)。

11. URI与URL区别

很多人会混淆这两个名词。

  • URL:(Uniform/Universal Resource Locator 的缩写,统一资源定位符)。

  • URI:(Uniform Resource Identifier 的缩写,统一资源标识符)(代表一种标准)。

关系:

  • URI 属于 URL 更高层次的抽象,一种字符串文本标准。就是说,URI 属于父类,而 URL 属于 URI 的子类。URL 是 URI 的一个子集。

  • 二者的区别在于,URI 表示请求服务器的路径,定义这么一个资源。而 URL 同时说明要如何访问这个资源(http://)。

CGI(通用网关接口)与环境变量

  • CGI程序

    • CGI是外部应用程序(CGI程序)与WEB服务器之间的接口标准,是在CGI程序和Web服务器之间传递信息的过程。

    • 服务器为客户端提供动态服务首先需要解决的是得到用户提供的参数再根据参数信息返回。为了和客户端进行交互,服务器需要先创建子进程,之后子进程执行相应的程序去为客户服务。CGI正是帮助我们解决参数获取、输出结果的。动态内容获取其实请求报文的头部和请求静态数据时完全相同,但请求的资源从静态的HTML文件变成了后台程序。服务器收到请求后fork()一个子进程,子进程执行请求的程序,这样的程序称为CGI程序(Python、Perl、C++等均可)。通常在服务器中我们会预留一个单独的目录(cgi-bin)用来存放所有的CGI程序,请求报文头部中请求资源的前缀都是/cgi-bin,之后加上所请求调用的CGI程序即可。所以上述流程就是:客户端请求程序 -> 服务器fork()子进程 -> 执行被请求程序。接下来需要解决的问题就是如何获取客户端发送过来的参数和输出信息怎么传递回客户端。

  • 环境变量

    对CGI程序来说,CGI环境变量在创建时被初始化,结束时被销毁。当CGI程序被HTTP服务器调用时,因为是被服务器fork()出来的子进程,所以其继承了其父进程的环境变量,这些环境变量包含了很多基本信息,请求头中和响应头中列出的内容(比如用户Cookie、客户机主机名、客户机IP地址、浏览器信息等),CGI程序所需要的参数也在其中。

    • GET方法下参数获取

      服务器把接收到的参数数据编码到环境变量QUERY_STRING中,在请求时只需要直接把参数写到URL最后即可,比如"http:127.0.0.1:80/cgi-bin/test?a=1&b=2&c=3",表示请求cgi-bin目录下test程序,’?‘之后部分为参数,多个参数用’&'分割开。服务器接收到请求后环境变量QUERY_STRING的值即为a=1&b=2&c=3。

      在CGI程序中获取环境变量值的方法是:getenv(),比如我们需要得到上述QUERY_STRING的值,只需要下面这行语句就可以了。

        char *value = getenv("QUERY_STRING");
      

      之后对获得的字符串处理一下提取出每个参数信息即可。

    • POST方法下参数获取

      POST方法下,CGI可以直接从服务器标准输入获取数据,不过要先从CONTENT_LENGTH这个环境变量中得到POST参数长度,再获取对应长度内容。

会话机制

HTTP作为无状态协议,必然需要在某种方式保持连接状态。这里简要介绍一下Cookie和Session。

  • Cookie

    • Cookie是客户端保持状态的方法。(身份认证等)

    • Cookie简单的理解就是存储由服务器发至客户端并由客户端保存的一段字符串。为了保持会话,服务器可以在响应客户端请求时将Cookie字符串放在Set-Cookie下,客户机收到Cookie之后保存这段字符串,之后再请求时候带上Cookie就可以被识别。

    • 除了上面提到的这些,Cookie在客户端的保存形式可以有两种,一种是会话Cookie一种是持久Cookie,会话Cookie就是将服务器返回的Cookie字符串保持在内存中,关闭浏览器之后自动销毁,持久Cookie则是存储在客户端磁盘上,其有效时间在服务器响应头中被指定,在有效期内,客户端再次请求服务器时都可以直接从本地取出。需要说明的是,存储在磁盘中的Cookie是可以被多个浏览器代理所共享的。

  • Session

    • Session是服务器保持状态的方法。(记录用户操作、识别用户等)

    • 首先需要明确的是,Session保存在服务器上,可以保存在数据库、文件或内存中,每个用户有独立的Session用户在客户端上记录用户的操作。我们可以理解为每个用户有一个独一无二的Session ID作为Session文件的Hash键,通过这个值可以锁定具体的Session结构的数据,这个Session结构中存储了用户操作行为。

  • 当服务器需要识别客户端时就需要结合Cookie了。每次HTTP请求的时候,客户端都会发送相应的Cookie信息到服务端。实际上大多数的应用都是用Cookie来实现Session跟踪的,第一次创建Session的时候,服务端会在HTTP协议中告诉客户端,需要在Cookie里面记录一个Session ID,以后每次请求把这个会话ID发送到服务器,我就知道你是谁了。如果客户端的浏览器禁用了Cookie,会使用一种叫做URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如sid=xxxxx这样的参数,服务端据此来识别用户,这样就可以帮用户完成诸如用户名等信息自动填入的操作了。

猜你喜欢

转载自blog.csdn.net/weixin_38337616/article/details/89058757