网络协议(七)应用层-HTTP

上篇文章介绍了传输层的TCP、UDP协议,在TCP/IP协议中,下三层(网络接口层,网络层,传输层)都是计算机系统联合其他硬件设备自己在干的事,身为程序员的我们平时对其感知不大。而应用层却是与程序开发息息相关的一层,如HTTP,HTTPS,DNS,FTP,SMTP等等,针对不同应用场景在应用层都有其对应的应用层协议。这篇文章就来研究下做WEB程序开发时接触最多的HTTP协议。

HTTP全称(HyperText Transfer Protocol),超文本传输协议,HTTP协议广泛用于浏览器与服务器,服务器与服务器之间的请求交互。因其是应用层的一个协议,所以服务对象必然是一个应用程序。通常来说,由一台服务器充当服务端,在上面部署一个能接收与发送HTTP请求的应用程序;客户端方面,最常见的就是浏览器,浏览器可以发送HTTP请求并接收响应内容,对程序员来说,由另一台服务器来充当客户端也是常见的事,两台服务器上的应用程序都可以向对方提供接口,所以它们可互为服务端与客户端。

HTTP特性

1.无连接性

http是一个应用层的协议,只是应用程序之间数据交互的一种格式定义。至于连接性,这是数据传输时才会用到的概念,即传输层才存在所谓连接,通常情况下也就是tcp连接(tcp相关概念请阅读上一篇文章:网络协议(六)传输层)。所以http天然不具备连接性。

http需要一个能保证可靠传输数据的下层协议来支持,所以一般来说是tcp充当其在传输层的合作协议,http要发送一个请求给对端服务,数据到传输层后,tcp通过三次握手建立连接后,才能发送这些应用数据。那tcp何时断开连接呢?在http1.0及之前的版本中,http的每一次请求都是很独立的,即每次请求结束后tcp就进行四次挥手断开连接。http1.1版本出来后,请求头默认加上Connection: keep-alive,即在一次请求后不再马上断开tcp的连接,而是保持一个tcp长连接,来避免多次http请求时tcp的频繁握手挥手,减少不必要的网络消耗,加快传输效率。

2.无状态性

HTTP本身是一种无状态协议,协议定义中并没有要求必须有一个会话标识,所以服务端收到的每次请求都会看做是一个独立的请求,和其他任何请求没有关联。

但是很多情况下我们需要一个标识来标记一次会话过程,在一次会话中保存一些上下文信息,比如需要登录验证的系统。基于这种需求,Web应用程序通常使用Cookie和Session来跟踪用户的状态。用户不带cookie头首次访问服务器后,服务器的http返回头中会通知浏览器存储一个cookie标识,如下图

浏览器接下来对这个ip或域名(与端口无关)访问时,http请求头中都会带上这个cookie标识,

服务端有个session的记录表来记录一次次会话,收到cookie标识后就可以对应上指定Session,这样一套cookie+session的机制就实现了http的会话保持功能。

3.基于请求-响应模型

客户端与服务端使用http协议通信时都是有来有回的,一次请求必然对应着一个应答。

HTTP协议规范

来看看HTTP长什么样子,通过一个例子来看

请求内容
POST /practice/gift/updateGift HTTP/1.1
Accept: application/json, text/plain, */*
Content-Length: 149
Content-Type: application/json;charset=UTF-8
Cookie: SESSION=ZjliZjhlZDEtMDk0YS00ZjA3LWJkMDItYTc3Nzk2ZTY1NGFh
Host: 47.94.211.120:8090
Origin: http://47.94.211.120:8090
Proxy-Connection: keep-alive
Referer: http://47.94.211.120:8090/
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36

[{"giftName":"一个掌声","price":10}]

请求内容的格式分为四大块:请求行,请求头,空行,消息体

返回内容
HTTP/1.1 200
Transfer-Encoding: chunked
Connection: keep-alive
Content-Type: application/json
Date: Thu, 14 Dec 2023 03:59:35 GMT
Keep-Alive: timeout=4
Proxy-Connection: keep-alive
Server: nginx/1.12.2

{"code":0,"message":"操作成功","data":null}

返回内容的格式也分为四大块:请求行,请求头,空行,消息体。其中,请求行的状态描述不是必须项。

可以看到,请求内容和返回内容的格式相差不大,主要区别在于第一行。下面具体看下第一行的内容都有啥待选项。

协议版本

协议版本就是http的版本,目前主流的还是1.1版本。

请求方法(八种方法)

  • GET。用于获取某些资源,比如查询操作。
  • POST。用于新建或更新资源。
  • PUT。用于更新资源,但是需要完整的更新,不能局部更新。
  • DELETE。用于删除资源
  • HEAD。与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回消息体,只传回状态行和响应头。
  • TRACE。回显服务器收到的请求,主要用于测试或诊断。
  • OPTIONS。这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用'*'来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作。
  • CONNECT。CONNECT方法可以开启一个客户端与所请求资源之间的双向沟通的通道,可以用来创建隧道(tunnel)。例如,CONNECT可以用来访问采用了SSL(HTTPS)协议的站点。

此外,特定的HTTP服务器还能够扩展自定义的方法。例如:PATCH,用于将局部修改应用到资源。

其中GET和POST是非常常用的方法。这两种方法基本能满足绝大多数应用场景(因为每种方法的用法只是一种约定用法,实际使用中能达到想要的效果就行)。如果应用程序用的是rest风格的api,那么还会用到PUT,PATCH,DELETE。剩余的几个在程序开发时就不太常见了。

状态码

HTTP协议定义了一系列状态码,用于表示服务器对请求的处理结果。这些状态码分为五类,每类都有特定的含义。以下是一些常见的HTTP状态码:

  • 1xx(信息性状态码): 表示请求已被接收,继续处理。

    • 100 Continue:服务器已收到请求的头部信息,客户端应该继续发送请求的剩余部分。
    • 101 Switching Protocols:服务器已经理解了客户端的请求,并将通过Upgrade消息头通知客户端切换协议。
  • 2xx(成功状态码): 表示请求已成功被服务器接收、理解、并接受。

    • 200 OK:请求成功。
    • 201 Created:请求已经被实现,而且有一个新的资源已经依据请求的需要而建立。
    • 204 No Content:服务器成功处理了请求,但不需要返回任何实体内容。
  • 3xx(重定向状态码): 表示需要客户端采取进一步的操作才能完成请求。

    • 301 Moved Permanently:请求的资源已永久移动到新位置。
    • 302 Found:请求的资源临时移动到新的位置(短链跳转常用)。
    • 304 Not Modified:资源未被修改,可以使用缓存的版本。
  • 4xx(客户端错误状态码): 表示客户端在请求时出现了错误。

    • 400 Bad Request:请求无效,服务器不理解请求的语法。
    • 401 Unauthorized:请求要求身份验证,需要提供有效的用户身份。
    • 403 Forbidden:服务器拒绝请求。
    • 404 Not Found:服务器找不到请求的资源。
  • 5xx(服务器错误状态码): 表示服务器在处理请求时发生了错误。

    • 500 Internal Server Error:服务器遇到了不知道如何处理的情况。
    • 502 Bad Gateway:服务器作为网关或代理,从上游服务器收到无效响应。
    • 503 Service Unavailable:服务器暂时不可用。

HTTP2.0

HTTP/2保留了HTTP/1.1的大部分语义,例如请求方法、状态码乃至URI和绝大多数HTTP头字段一致。而HTTP/2采用了新的方法来编码、传输客户端和服务器之间的数据。

HTTP2.0版本和1.1版本的区别:

  1. 多路复用(Multiplexing): HTTP/2.0支持多路复用,允许在单个连接上同时发送多个请求和响应,而不需要按照顺序进行阻塞。这提高了并发性,减少了延迟。

  2. 二进制传输: HTTP/2.0在传输数据时使用二进制格式,而不是HTTP/1.1中的文本格式。这使得协议的解析更加高效,并且可以减少错误。但也使得直接查看和调试成为挑战。

  3. 头部压缩: HTTP/2.0使用HPACK算法对请求和响应头部进行压缩,减少了传输的数据量。这有助于降低带宽的使用,特别是对于包含大量重复头部的请求。

  4. 流(Stream): HTTP/2.0引入了流的概念,一个流代表一个双向的、独立的逻辑通道,可以在同一个连接上传输多个流。每个流都有一个唯一的标识符,允许并发处理多个请求和响应。

  5. 服务器推送(Server Push): HTTP/2.0允许服务器在客户端请求之前推送资源,以提高性能。服务器可以主动将与请求相关的资源推送给客户端,避免了客户端再次发起请求的延迟。

  6. 优先级(Priority): HTTP/2.0支持请求的优先级,允许客户端指定对请求的优先级,而服务器则可以使用这些信息来调整响应的顺序。

HTTP1.1版本工作方式相当于半双工方式,2.2版本相当于全双工。关于双工概念,网络上有个比喻很到位:

双工是相对与单工而言的,单工是单方面传输的,比如有一条路,是从A到B,那么单工就是单向行道,只能从A到B不能从B到A,而半双工就是这条路能从A到B,也能从B到A,但不能同时进行,从A到B时不能从B到A,从B到A时不能从A到B,而全双工就是双行道,能从A到B,也可以从B到A,而且可以同时进行。因此单工就相当于BB机,别人能给你发,但你不能直接回;半双工就是对讲机,一个说完一个说;不能同时进行;全双工就是手机,双方可能同时进行。这就是单工,半双工与全双工的区别。

回到http上,http1.1只能一个一个请求排队发,服务端一个一个排队进行响应。而2.0可以同时将多个请求发给服务端,服务端也可以同时接收多个请求。这都是浏览器和服务器建立了一个tcp连接的前提下。现在的浏览器可能会对同一个host同时申请多个tcp连接,方便它进行并发请求。

HTTP的沟通都是明文沟通,所以程序开发时一般使用HTTP来进行调试,方便观察请求与返回结果,但是明文的话就存在安全性的问题。HTTPS在HTTP的基础上增加了加密逻辑,线上部署时一般都会使用HTTPS的形式,下篇文章就来研究下HTTPS。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值