tcp 和http 网络知识
1. 请简述TCP和HTTP的定义与基本概念
- TCP:即传输控制协议(Transmission Control Protocol),是一种面向连接的、可靠的、基于字节流的传输层通信协议。它为互联网中的数据通信提供稳定的传输机制,在不可靠的IP层之上,通过确认、重传和错误检测等技术确保数据正确到达。比如在文件传输场景中,TCP保证文件的每个字节都能准确无误地从源端传输到目的端。
- HTTP:超文本传输协议(HyperText Transfer Protocol),是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范。常见的网页浏览就是基于HTTP协议,浏览器向服务器发送HTTP请求获取网页资源,服务器返回对应的HTTP响应。
2. TCP是如何保证数据的可靠性的
TCP通过多种机制保证数据可靠性:
- 序列号与确认应答:TCP为每个发送的字节编号,接收方收到数据后,会发送ACK确认包给发送方,ACK包中包含确认号,告知发送方下一个期望接收的数据字节序号。通过这种方式,发送方可以确认数据是否被正确接收。
- 超时重传:发送方发送数据后会启动一个定时器,如果在规定时间内没有收到对应的ACK确认,就会认为数据丢失,重新发送该数据。例如,在网络不稳定时,数据包可能丢失,超时重传机制确保数据最终能被送达。
- 流量控制:利用滑动窗口机制,接收方通过在ACK包中告知发送方自己的接收窗口大小(即还能接收的数据量),发送方根据接收窗口大小控制发送速率,避免发送过快导致接收方缓冲区溢出。
- 拥塞控制:包括慢启动、拥塞避免、快速重传和快速恢复等算法。发送方维护一个拥塞窗口,根据网络拥塞情况动态调整。如在网络拥塞时,减少数据发送量,防止网络进一步恶化。
3. 说一说TCP的三次握手过程,为什么是三次握手
三次握手是建立TCP连接的过程:
- 第一次握手:客户端向服务器发送SYN(同步序列编号)包,该包中包含客户端的初始序列号(例如x),此时客户端进入SYN_SENT状态,表明客户端希望与服务器建立连接。
- 第二次握手:服务器接收到客户端的SYN包后,向客户端发送SYN - ACK包。这个包包含两部分,一是对客户端SYN的确认(ACK = x + 1),二是服务器自己的初始序列号(例如y),此时服务器进入SYN_RCVD状态。
- 第三次握手:客户端收到服务器的SYN - ACK包后,向服务器发送ACK包,确认收到服务器的SYN - ACK(ACK = y + 1),此时客户端和服务器都进入ESTABLISHED状态,连接建立成功。
TCP需要三次握手主要有两个原因:
- 防止旧的重复连接引起混乱:在网络状况复杂或较差时,发送方可能会连续发送多次建立连接请求。若只有两次握手,接收方无法判断请求是正常的还是过期的,可能导致错误连接。三次握手能让双方确认对方收到了自己的初始序列号,避免这种情况。
- 同步初始化序列号:TCP需要初始化序列号保证消息顺序。两次握手无法确认序列号是否正常,四次握手则会浪费系统资源,三次握手是最优解。
4. 请阐述HTTP常见的请求方法及其区别,比如GET和POST
HTTP常见的请求方法有GET、POST、PUT、DELETE、HEAD等,其中GET和POST区别如下:
- 语义用途:
- GET:从服务器获取指定资源,是只读操作。例如在浏览器中输入网址访问网页,就是使用GET方法获取网页资源。
- POST:根据请求负荷(报文body)对指定资源做出处理,通常用于新增或提交数据,如用户注册、表单提交数据等场景。
- 安全性与幂等性:
- GET:从RFC规范定义看,GET方法安全且幂等。安全指不会破坏服务器资源,幂等指多次执行操作结果相同。实际开发中若用GET实现新增或删除数据,则不具备安全和幂等性。
- POST:因为会修改服务器资源,所以不安全,且多次提交可能创建多个资源,不幂等。但实际若用POST实现查询数据,则安全且幂等。
- 数据传输位置与可见性:
- GET:数据通过URL的查询参数传递,在浏览器地址栏可见。例如:
https://example.com/search?q=apple
,其中q=apple
就是查询参数。 - POST:数据放在请求体(body)中传输,浏览器地址栏不可见,但抓包工具可查看。
- GET:数据通过URL的查询参数传递,在浏览器地址栏可见。例如:
- 缓存性:
- GET:可被缓存,浏览器和代理服务器(如Nginx)都能对GET请求的数据做缓存,且浏览器中GET请求可保存为书签。
- POST:大部分实现中不可缓存,浏览器一般不会缓存POST请求,也不能保存为书签。
5. 当在浏览器中输入一个URL并回车后,从网络层面描述计算机做了哪些工作步骤
- DNS解析:浏览器首先检查自身缓存,看是否有该URL对应的IP地址。若没有,则向本地DNS服务器发送查询请求。本地DNS服务器若缓存中有记录,直接返回IP;没有则向根DNS服务器、顶级域名服务器等依次查询,最终获取到目标URL对应的IP地址。
- TCP连接建立:浏览器获取IP地址后,与目标服务器建立TCP连接,通过三次握手过程(客户端发送SYN包、服务器返回SYN - ACK包、客户端再发送ACK包),成功建立可靠连接。
- HTTP请求发送:TCP连接建立后,浏览器构建HTTP请求报文,包括请求行(如GET /index.html HTTP/1.1)、请求头(如User - Agent、Accept等),若为POST请求还会有请求体。然后将请求报文通过TCP连接发送给服务器。
- 服务器处理请求与响应:服务器接收到HTTP请求后,根据请求的URL和方法,找到对应的资源或执行相应的业务逻辑。处理完成后,构建HTTP响应报文,包含状态行(如HTTP/1.1 200 OK)、响应头(如Content - Type、Content - Length等)和响应体(如网页的HTML内容),并通过TCP连接返回给浏览器。
- TCP连接关闭:浏览器接收完响应数据后,若不需要再与服务器通信,会通过四次挥手过程关闭TCP连接(客户端发送FIN包、服务器返回ACK包、服务器再发送FIN包、客户端返回ACK包)。
- 浏览器渲染页面:浏览器根据HTTP响应中的Content - Type等信息,对响应体中的数据进行解析和渲染。若响应内容是HTML页面,浏览器会解析HTML、CSS和JavaScript,构建DOM树,渲染页面并展示给用户。
6. 简述HTTP协议的无状态性及其带来的问题与解决方案
- 无状态性定义:HTTP协议的无状态性指服务器不保留关于客户端的任何状态信息。每个HTTP请求都是独立的,服务器无法区分这是同一个客户端的连续请求还是不同客户端的请求。例如,用户在一个页面登录后,再访问该网站的其他页面,服务器无法直接知道该用户已登录。
- 带来的问题:在需要跟踪用户状态的应用场景中,如电商购物车、用户登录状态保持等,无状态性使得服务器难以处理。每次请求都需额外机制来识别用户身份和状态,增加开发复杂度。
- 解决方案:
- Cookie:服务器在HTTP响应头中添加Set - Cookie字段,将一些状态信息(如用户ID、登录状态标识等)发送给客户端。客户端收到后,在后续的HTTP请求头中带上Cookie字段,服务器通过解析Cookie来识别用户状态。
- Session:服务器为每个客户端分配一个唯一的Session ID,通常通过Cookie将Session ID发送给客户端。服务器在内存或存储中维护Session数据,客户端每次请求时,服务器根据Session ID找到对应的Session数据,获取用户状态等信息。
- Token:常用于前后端分离的应用中。服务器验证用户身份后,生成一个Token(如JWT,JSON Web Token),包含用户身份等信息,返回给客户端。客户端在后续请求中,将Token放在请求头或其他位置发送给服务器,服务器通过验证Token来确认用户身份和权限。
7. 讲讲HTTP1.0和HTTP1.1的主要区别
- 连接方式:
- HTTP1.0:只支持短连接,浏览器每次请求都需与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接。这意味着对于包含多个资源(如多个图片)的网页,会频繁建立和断开TCP连接,增加开销和延迟。
- HTTP1.1:支持持久连接(默认开启),在一个TCP连接上可传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。一个包含许多图像的网页文件的多个请求和应答可在一个连接中传输,但每个单独的网页文件的请求和应答仍需使用各自的连接。通过设置
Connection: Keep - Alive
头字段开启持久连接。
- Host字段:
- HTTP1.0:请求消息中的URL没有传递主机名(hostname),因为当时认为每台服务器都绑定一个唯一的IP地址。
- HTTP1.1:增加了
Host
字段,随着虚拟主机技术发展,一台物理服务器上可能存在多个共享一个IP地址的虚拟主机。通过Host
字段,服务器能知道客户端请求的具体虚拟主机,如Host: www.example.com
。
- 缓存处理:
- HTTP1.0:缓存功能有限,对缓存的控制不够精细。
- HTTP1.1:引入了更多缓存相关的字段和机制,如
Cache - Control
头字段,可设置多种缓存策略,包括缓存过期时间、是否可缓存等,比HTTP1.0中简单的Expires
字段更灵活和强大。
- 错误处理:
- HTTP1.0:错误状态码相对较少,对一些错误情况的描述不够细致。
- HTTP1.1:定义了更多详细的错误状态码,如409 Conflict(表示请求与资源当前状态冲突)、410 Gone(表示资源已永久删除)等,能更准确地反馈服务器处理请求时遇到的问题。
8. 描述一下HTTP请求和响应的报文格式
- HTTP请求报文格式:
- 请求行:由请求方法(如GET、POST)、请求URL和HTTP协议版本组成,例如
GET /index.html HTTP/1.1
。 - 请求头:包含一系列键值对,用于传递关于客户端环境、请求内容等信息。常见的请求头有
User - Agent
(用于标识客户端类型,如浏览器名称和版本)、Accept
(声明客户端可接受的数据类型)、Accept - Encoding
(声明可接受的压缩方法)、Cookie
(用于传递客户端存储的Cookie信息)等。每个请求头占一行,格式为Header - Name: Header - Value
。 - 空行:请求头和请求体之间用一个空行分隔,标识请求头结束。
- 请求体:GET请求一般没有请求体,POST请求时,请求体包含要提交给服务器的数据,如表单数据、JSON格式数据等。数据格式根据
Content - Type
头字段指定,例如application/x - www - form - urlencoded
表示表单数据,application/json
表示JSON格式数据。
- 请求行:由请求方法(如GET、POST)、请求URL和HTTP协议版本组成,例如
- HTTP响应报文格式:
- 状态行:由HTTP协议版本、状态码和状态描述组成,例如
HTTP/1.1 200 OK
。状态码表示请求处理的结果,如200表示成功,404表示资源未找到。 - 响应头:同样是一系列键值对,用于传递关于服务器环境、响应内容等信息。常见的响应头有
Content - Type
(表示响应内容的数据类型,如text/html
表示HTML页面)、Content - Length
(表示响应内容的长度)、Set - Cookie
(用于在客户端设置Cookie)、Cache - Control
(控制缓存策略)等。 - 空行:响应头和响应体之间用空行分隔。
- 响应体:包含服务器返回给客户端的数据,如HTML页面内容、图片二进制数据、JSON格式的API响应数据等,具体内容根据请求的资源和服务器处理结果而定。
- 状态行:由HTTP协议版本、状态码和状态描述组成,例如