计算机网络

233 阅读14分钟

TCP数据报结构以及三次握手

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立连接,传输完毕后还要断开连接。

客户端在收发数据前要使用 connect() 函数和服务器建立连接。建立连接的目的是保证IP地址、端口、物理链路等正确无误,为数据的传输开辟通道。

TCP数据报结构

tcp.jpg

  1. 序号:Seq(Sequence Number)序号占32位,用来标识从计算机A发送到计算机B的数据包的序号,计算机发送数据时对此进行标记。
  2. 确认号:Ack(Acknowledge Number)确认号占32位,客户端和服务器端都可以发送,Ack = Seq + 1。
  3. 标志位:每个标志位占用1Bit,共有6个,分别为 URG、ACK、PSH、RST、SYN、FIN,具体含义如下:
  • URG:紧急指针(urgent pointer)有效。
  • ACK:确认序号有效。
  • PSH:接收方应该尽快将这个报文交给应用层。
  • RST:重置连接。
  • SYN:建立一个新连接。
  • FIN:断开一个连接。

连接的建立(三次握手)

tcp_conn.jpg
客户端调用 socket() 函数创建套接字后,因为没有建立连接,所以套接字处于CLOSED状态;服务器端调用 listen() 函数后,套接字进入LISTEN状态,开始监听客户端请求。

这个时候,客户端开始发起请求:

  1. 当客户端调用 connect() 函数后,TCP协议会组建一个数据包,并设置SYN标志位,表示该数据包是用来建立同步连接的。同时生成一个随机数字 1000,填充“序号(Seq)”字段,表示该数据包的序号。完成这些工作,开始向服务器端发送数据包,客户端就进入了SYN-SEND状态。

  2. 服务器端收到数据包,检测到已经设置了SYN标志位,就知道这是客户端发来的建立连接的“请求包”。服务器端也会组建一个数据包,并设置SYN和ACK标志位,SYN表示该数据包用来建立连接,ACK用来确认收到了刚才客户端发送的数据包。

    服务器生成一个随机数 2000,填充“序号(Seq)”字段。2000 和客户端数据包没有关系。
    服务器将客户端数据包序号(1000)加1,得到1001,并用这个数字填充“确认号(Ack)”字段。
    服务器将数据包发出,进入SYN-RECV状态。

  3. 客户端收到数据包,检测到已经设置了SYN和ACK标志位,就知道这是服务器发来的“确认包”。客户端会检测“确认号(Ack)”字段,看它的值是否为 1000+1,如果是就说明连接建立成功。

    接下来,客户端会继续组建数据包,并设置ACK标志位,表示客户端正确接收了服务器发来的“确认包”。同时,将刚才服务器发来的数据包序号(2000)加1,得到2001,并用这个数字来填充“确认号(Ack)”字段。

    客户端将数据包发出,进入ESTABLISED状态,表示连接已经成功建立。

  4. 服务器端收到数据包,检测到已经设置了ACK标志位,就知道这是客户端发来的“确认包”。服务器会检测“确认号(Ack)”字段,看它的值是否为 2000+1,如果是就说明连接建立成功,服务器进入ESTABLISED状态。

至此,客户端和服务器都进入了ESTABLISED状态,连接建立成功,接下来就可以收发数据了。

说明

三次握手的关键是要确认对方收到了自己的数据包,这个目标就是通过“确认号(Ack)”字段实现的。计算机会记录下自己发送的数据包序号 Seq,待收到对方的数据包后,检测“确认号(Ack)”字段,看Ack = Seq + 1是否成立,如果成立说明对方正确收到了自己的数据包。

TCP四次握手断开连接

建立连接非常重要,它是数据正确传输的前提;断开连接同样重要,它让计算机释放不再使用的资源。如果连接不能正常断开,不仅会造成数据传输错误,还会导致套接字不能关闭,持续占用资源,如果并发量高,服务器压力堪忧。

tcp_disconn.jpg

建立连接后,客户端和服务器都处于ESTABLISED状态。这时,客户端发起断开连接的请求:

  1. 客户端调用 close() 函数后,向服务器发送FIN数据包,进入FIN_WAIT_1状态。FIN 是 Finish 的缩写,表示完成任务需要断开连接。

  2. 服务器收到数据包后,检测到设置了 FIN 标志位,知道要断开连接,于是向客户端发送ACK数据包,进入CLOSE_WAIT状态。

    注意:服务器收到请求后并不是立即断开连接,而是先向客户端发送“确认包”,告诉它我知道了,我需要准备一下才能断开连接。

  3. 客户端收到“确认包”后进入FIN_WAIT_2状态,等待服务器准备完毕后再次发送数据包。

  4. 等待片刻后,服务器准备完毕,可以断开连接,于是再主动向客户端发送 FIN 包,告诉它我准备好了,断开连接吧。然后进入LAST_ACK状态。

  5. 客户端收到服务器的 FIN 包后,再向服务器发送 ACK 包,告诉它你断开连接吧。然后进入TIME_WAIT状态。

  6. 服务器收到客户端的 ACK 包后,就断开连接,关闭套接字,进入CLOSED状态。

关于 TIME_WAIT 状态的说明

客户端最后一次发送 ACK包后进入 TIME_WAIT 状态,而不是直接进入 CLOSED 状态关闭连接,这是为什么呢?

客户端最后一次向服务器回传ACK包时,有可能会因为网络问题导致服务器收不到,服务器会再次发送 FIN 包,如果这时客户端完全关闭了连接,那么服务器无论如何也收不到ACK包了,所以客户端需要等待片刻、确认对方收到ACK包后才能进入CLOSED状态。那么,要等待多久呢?

数据包在网络中是有生存时间的,超过这个时间还未到达目标主机就会被丢弃,并通知源主机。这称为报文最大生存时间(MSL,Maximum Segment Lifetime)。TIME_WAIT 要等待 2MSL 才会进入 CLOSED 状态。ACK 包到达服务器需要 MSL 时间,服务器重传 FIN 包也需要 MSL 时间,2MSL 是数据包往返的最大时间,如果 2MSL 后还未收到服务器重传的 FIN 包,就说明服务器已经收到了 ACK 包。

计算机网络体系结构

image.png

1. 五层协议

  • 应用层 :为特定应用程序提供数据传输服务,例如 HTTP、DNS 等协议。数据单位为报文。
  • 传输层 :为进程提供通用数据传输服务。由于应用层协议很多,定义通用的传输层协议就可以支持不断增多的应用层协议。运输层包括两种协议:传输控制协议 TCP,提供面向连接、可靠的数据传输服务,数据单位为报文段;用户数据报协议 UDP,提供无连接、尽最大努力的数据传输服务,数据单位为用户数据报。TCP 主要提供完整性服务,UDP 主要提供及时性服务。
  • 网络层 :为主机提供数据传输服务。而传输层协议是为主机中的进程提供数据传输服务。网络层把传输层传递下来的报文段或者用户数据报封装成分组。
  • 数据链路层 :网络层针对的还是主机之间的数据传输服务,而主机之间可以有很多链路,链路层协议就是为同一链路的主机提供数据传输服务。数据链路层把网络层传下来的分组封装成帧。
  • 物理层 :考虑的是怎样在传输媒体上传输数据比特流,而不是指具体的传输媒体。物理层的作用是尽可能屏蔽传输媒体和通信手段的差异,使数据链路层感觉不到这些差异。

2. OSI

其中表示层和会话层用途如下:

  • 表示层 :数据压缩、加密以及数据描述,这使得应用程序不必关心在各台主机中数据内部格式不同的问题。

  • 会话层 :建立及管理会话。

    五层协议没有表示层和会话层,而是将这些功能留给应用程序开发者处理。

3. TCP/IP

它只有四层,相当于五层协议中数据链路层和物理层合并为网络接口层。

TCP/IP 体系结构不严格遵循 OSI 分层概念,应用层可能会直接使用 IP 层或者网络接口层。

TCP可靠传输、滑动窗口、流量控制、拥塞控制🔗

HTTP 状态码

服务器返回的 响应报文 中第一行为状态行,包含了状态码以及原因短语,用来告知客户端请求的结果。

状态码类别含义
1XXInformational(信息性状态码)接收的请求正在处理
2XXSuccess(成功状态码)请求正常处理完毕
3XXRedirection(重定向状态码)需要进行附加操作以完成请求
4XXClient Error(客户端错误状态码)服务器无法处理请求
5XXServer Error(服务器错误状态码)服务器处理请求出错

1XX 信息

  • 100 Continue :表明到目前为止都很正常,客户端可以继续发送请求或者忽略这个响应。

2XX 成功

  • 200 OK
  • 204 No Content :请求已经成功处理,但是返回的响应报文不包含实体的主体部分。一般在只需要从客户端往服务器发送信息,而不需要返回数据时使用。
  • 206 Partial Content :表示客户端进行了范围请求,响应报文包含由 Content-Range 指定范围的实体内容。在HTTP1.0中存在带宽的浪费,不能只请求对象的一部分,请求整个对象,而HTTP1.1在请求头引入了range头域允许只请求资源的某个部分,返回状态码206(Partial Content)。

3XX 重定向

  • 301 Moved Permanently :永久性重定向
  • 302 Found :临时性重定向 301重定向是一种永久重定向,而302跳转是暂时的跳转。
    在使用域名跳转的情况下,301重定向比较常用。搜索引擎在抓取新内容的时候,还会把原本的旧网址用重定向之后的新网址代替。就比如说,我们访问http://www.baidu.com,网站页面会跳转到https://www.baidu.com,发送请求之后,就会返回301状态码,然后返回一个位置以提示新地址,浏览器就会访问这个新地址。

302跳转,可以在登陆用户访问用户中心的时候重定向到登录页面。接着,搜索引擎就会获取新内容,并保留旧的URL。由于服务器返回的是302代码,搜索引擎会认为新的网址只是暂时的。

4XX 客户端错误

  • 400 Bad Request :请求报文中存在语法错误。 服务器不理解请求的语法。
  • 401 Unauthorized :请求要求身份验证。对于登录后请求的网页,服务器可能返回此响应。
  • 403 Forbidden :请求被拒绝。
  • 404 Not Found

5XX 服务器错误

  • 500 Internal Server Error :服务器正在执行请求时发生错误。
  • 502(错误网关)服务器作为网关或代理,从上游服务器收到无效响应。
  • 503 Service Unavailable :服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。

PUT和POST

PUT请求:如果两个请求相同,后一个请求会把第一个请求覆盖掉。(所以PUT用来改资源)
Post请求:后一个请求不会把第一个请求覆盖掉。(所以Post用来增资源)

从输入一个URL到显示页面的过程

输入URL域名解析建立TCP连接浏览器向服务端发送HTTP请求服务端接收请求并返回HTTP请求浏览器进行页面渲染

注意:

  • DNS解析域名,过程如下:
    1. 浏览器缓存:先查找浏览器中缓存的DNS记录,浏览器一般会缓存DNS记录2-30分钟不等。
    2. 系统缓存:如果浏览器缓存未命中,浏览器会通过系统调用查找系统中的记录(windows下为gethostbyname)。
    3. 路由器缓存:如果本地hosts没有该域名,则向外部DNS服务器查询。
    4. 至此,已经拿到了IP地址,开始建立TCP连接。
  • 通过三次握手建立TCP连接
  • 浏览器向服务端发送HTTP请求的请求信息包括请求头和请求体 http.png

补充:

  • 持久连接:既然维持 TCP 连接好处这么多,HTTP/1.1 就把 Connection 头写进标准,并且默认开启持久连接,浏览器和服务器之间是会维持一段时间的 TCP 连接,不会一个请求结束就断掉。,除非请求中写明 Connection: close。
  • 一个 TCP 连接是可以发送多个 HTTP 请求的。

HTTP/1.1

HTTP/1.1主要增加了:

  1. keep-alive选项,建立TCP连接后,一定时间内不会断开,其他请求都可以使用这条连接。

    • HTTP/1.0每一个请求都会重新建立一个TCP连接,一旦响应返回,就关闭连接。
  2. pipeLining管道,通过这个管道,浏览器的多个请求可以同时发到服务器,但是服务器的响应只能够一个接着一个的返回( 但各大浏览器有些不支持/默认关闭,因此这功能可以说是鸡肋)

HTTP2.0与HTTP1.1的区别

二进制分帧

HTTP2.0的优化核心是「二进制传输」,在HTTP1.x中都是通过「文本」的方式传输数据。
为了保证HTTP不受影响,在应用层(HTTP2.0)和传输层(TCP或UDP)之间增加了一个「二进制分帧层」。在二进制分帧层上,HTTP2.0将传输的信息分割为更小的帧,并采用二进制编码。

多路复用 (Multiplexing)

  • 在HTTP/1.1中,「浏览器在同一时间,针对同一域名的请求有数量限制,超过限制数目就会被阻塞」。
  • 而HTTP2.0中,基于二进制分帧层,HTTP2.0可以在共享TCP连接的基础上同时发送请求和响应。HTTP消息被分解为独立的帧,而不破坏消息本身的语义,交错发出去,在另一端根据流标识符和首部将他们重新组装起来。

首部压缩

  • HTTP每次请求或响应都会携带首部信息用于描述资源属性。
  • HTTP2.0使用HPACK算法对请求或响应的首部信息进行压缩,减小了header的大小,也减小了传输时的开销。

服务器推送

  • HTTP2.0让服务器可以「将响应主动“推送”到浏览器缓存中」。服务端根据客户端的请求,提前返回多个响应,推送额外的资源给客户端。

HTTP和HTTPS的区别

  1. HTTP使用明文传输,未加密,安全性差;HTTPS =SSL(TLS) + HTTP是使用SSL(TLS)协议加密的,安全性好。
  2. HTTP端口号80,HTTPS端口号443。
  3. HTTP响应速度比HTTPS快,HTTP使用TCP三次握手建立连接,共要传输3个数据包;HTTPS除了TCP的三个包,还要追加上SSL握手的9个包,一共是12个包,所以HTTPS比HTTP更耗费资源。

SSL协议基本运行过程

  1. 客户端向服务器端索要并验证公钥。
  2. 双方协商生成"对话密钥"。
  3. 双方采用"对话密钥"进行加密通信。 其中,前两个阶段,被称为“握手阶段”。