1. HTTP简介
HTTP是一种传输超文本数据的应用层协议,它是万维网的基础,用于在CS间传递信息。HTTP是无状态的,意味着每个单独的请求都是独立的,服务器并不保存前一次请求的信息。
2. HTTP组成
HTTP的组成主要包括两个部分:请求(Request)和响应(Response)。
2.1 请求报文组成
(1)请求行
请求行包括请求方法、请求的URL以及协议版本。
示例:GET /index.html HTTP/1.1
(2)请求头
包括与请求相关的各种信息。如User-Agent、Accept、Content-Type等。
(3)空白行
在HTTP请求中,空白行位于请求头部的末尾和请求体的开始之间。如果请求中不包含请求体,则空白行后面直接结束请求。如果请求包含请求体,则空白行后面是请求体的内容。
(4)请求体
发送给服务端的数据
2.2 响应报文组成
(1)状态行
状态行包括协议版本、状态码和状态消息
示例:HTTP/1.1 200 OK
(2)响应头
包括与响应相关的信息,如Server、Content-Type、Content-Length等。
(3)空白行
在HTTP响应中,空白行位于响应头部的末尾和响应体的开始之间。响应头部和响应体之间必须有一个空白行来分隔它们。
(4)响应体
服务端返回的内容,如HTML页面、JSON数据、图片等。
2.3 协议报文字段
(1)Accept
Accept字段允许客户端指定它所能够理解并希望从服务端接收到的数据类型。这种机制有助于服务器根据客户端的偏好来提供合适的内容。例如:Accept: text/html,application/xhtml+xml, application/xml;q=0.9,*/*;q=0.8。这个例子中,客户端首先希望接收text/html类型的内容,其次是application/xhtml+xml和application/xml,最后是一个通配符*/*,表示如果上述类型都不可用,则接受任何类型的内容。q参数用于指定相对优先级,q=0.9表示优先级略低于text/html,而q=0.8表示优先级更低。
(2)Accept-Charset
Accept-Charset字段允许客户端指定它所支持的字符集,以便服务器可以根据这些信息来选择合适的字符集编码返回给客户端。
(3)Content-Type
Content-Type是服务端向客户端发送的头,代表内容的媒体类型和编码格式,是对Accept头和Accept-Charset头的统一应答。
(4)Accept-Language
客户端期望服务器返回的内容的语言。
(5)Content-Language
服务端对Accept-Language的应答
(6)Content-Length
在请求头里,指定了随请求发送的数据的字节长度。服务器在接收数据时会使用这个信息来知道何时所有数据都已经接收完毕,可以开始处理请求。在响应头里,指定了响应体的长度。客户端使用这个信息来知道需要读取多少数据才能完整地接收到响应体。
(7)Allow
响应头字段,告诉客户端可以使用哪些方法来与服务器上的特定资源进行交互。
(8)Connection
控制客户端和服务器之间的连接管理
(9)Host
Host 字段主要用于指定请求的目标服务器的主机名和端口号
(10)Server
Server字段通常位于响应头部的其他字段之后,用于标识服务端的名称及版本号。
(11)Range
请求头字段,支持从服务器请求资源的部分或全部内容。这一特性在下载大文件时尤其有用,因为它允许客户端实现多线程下载和断点续传。
(12)Content-Range
响应头字段,在服务器响应部分请求的资源时,告知客户端当前发送的数据的范围以及整个资源的总大小。
(13)Location
响应头字段,主要用于重定向。通知客户端去请求一个新的URI地址获取资源。
(14)Referer
请求头字段,表示请求的发起来源URI。如果你从A页面跳转到B页面,那么请求B页面的请求头里面就会有Referer信息,它的值就是A页面的访问地址。通过追踪Referer,可得出资源页面之间复杂的跳转链,它非常适合用于网页的数据分析和路径优化。
(15)Retry-After
响应头字段,在服务端无法立即处理请求时,向客户端提供何时可以重试请求的信息。
(16)User-Agent
User-Agent字段包含了发起请求的客户端软件的信息,如浏览器类型、版本、操作系统以及可能的其他细节。这个信息对于服务器来说非常重要,因为它允许服务器根据客户端的能力来优化响应内容,或者根据不同的客户端提供不同的服务。
3. TCP的三次握手和四次挥手
TCP通过三次请求响应建立连接,通过四次请求响应断开连接。通常我们称为TCP的三次握手和四次挥手。
三次握手简单图例如下:
第一次握手
当客户端向服务器发起连接请求时,客户端会发送同步序列标号SYN到服务器,在这里我们设SYN为m,等待服务器确认,这时客户端的状态为SYN_SENT。
第二次握手
当服务器收到客户端发送的SYN后,服务器要做的是确认客户端发送过来的SYN,在这里服务器发送确认包ACK,这里的ACK为m+1,意思是说“我收到了你发送的SYN了”,同时,服务器也会向客户端发送一个SYN包,这里我们设SYN为n。这时服务器的状态为SYN_RECV。
第三次握手
客户端收到服务器发送的SYN和ACK包后,需向服务器发送确认包ACK,“我也收到你发送的SYN了,我这就给你发个确认过去,然后我们即能合体了”,这里的ACK为n+1,发送完毕后,客户端和服务器的状态为ESTABLISH,即TCP连接成功。
在三次握手中,客户端和服务器端都发送两个包SYN和ACK,只不过服务器端的两个包是一次性发过来的,客户端的两个包是分两次发送的。
四次挥手简单图例如下:
当A端和B端要断开连接时,需要四次挥手。断开连接请求可以由客户端发出,也可以由服务器端发出。
第一次挥手
A端向B端请求断开连接时会向B端发送一个带有FIN标记的报文段,这里的FIN是FINish的意思。
第二次挥手
B端收到A发送的FIN后,B段现在可能现在还有数据没有传完,所以B端并不会马上向A端发送FIN,而是先发送一个确认序号ACK。
第三次挥手
当B端的事情忙完了,那么此时B端就可以断开连接了,此时B端向A端发送FIN序号,意思是这次可以断开连接了。
第四次挥手
A端收到B端发送的FIN后,会向B端发送确认ACK,然后经过两个MSL时长后断开连接。
总的来说,建立连接的三次握手保证了双方的通信能力和初始化序列号的同步,从而确保后续的数据传输能够有效可靠地进行。关闭连接的四次挥手则保证了数据的完整传输和连接的正常终止,避免了数据丢失或者后续混乱的情况。