• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

秋招保驾护航——计算机网络

武飞扬头像
小猪皮皮呆
帮助2

传输层

传输层位于应用层和网络层中间,在因特网协议中,我们关注TCP和UDP协议。先来了解一下传输层提供的服务:

  • 传输层协议为运行在不同进程之间提供了逻辑通信

  • 应用进程通过使用传输层提供的逻辑通信功能彼此发送报文,无需考虑承载这些报文的物理基础设施的细节

  • 传输层协议是在端系统实现的:

    • 发送端,运输层将从应用进程接收到的报文转换为报文段
    • 为每个报文段加上一个运输层首部,生成一个运输层报文段
    • 传递这些报文段给网络层
    • 网络层将其封装成数据包向目的地发送
    • 在接收端,网络层从数据包中提取运输层报文段,并将其提交给上层运输层
    • 运输层处理接收到的报文段
    • 将报文段中的数据为接受应用进程使用

UPD和TCP提供的服务模型

  • 运输层的多路复用多路分解
  • 提供完整性检查

TCP额外提供的服务

  • 可靠数据传输服务
  • 拥塞控制

1. TCP和UDP的区别

TCP是一个面向连接的、可靠的、基于字节流的传输层协议。而UDP是一个面向无连接的传输层协议。

(1)面向连接服务

  • 面向连接服务:在进行报文流动前,TCP让客户和服务器互相进行交换运输层控制信息。
  • 这个所谓的握手过程提醒客户和服务器,让他们为大量的分组的到来做好准备
  • 一个TCP连接在两个进程的套接字之间建立后,双方可以在此连接上进行报文收发
  • 当报文放松结束时,必须拆除该连接。

(2)可靠数据传送服务

  • 通信进程之间依靠TCP能够无差错、按适当顺序交付所有的数据

(3)面向字节流

  • UDP 的数据传输是基于数据报的,这是因为仅仅只是继承了 IP 层的特性,而 TCP 为了维护状态,将一个个 IP 包变成了字节流。

2. TCP连接的三次握手

  • 客户端发送SYN,表明要向服务器建立连接。同时带上序列号ISN

  • 服务器返回ACK(序号为客户端序列号 1)作为确认。同时发送SYN作为应答(SYN的序列号为服务端唯一的序号)

  • 客户端发送ACK确认收到回复(序列号为服务端序列号 1)

    学新通

1、为什么是是三次握手不是两次或四次?

因为,tcp连接是全双工的,数据在两个方向上能同时传递。所以要确保双方,同时能发数据和收数据

  • 第一次握手:证明了发送方能发数据
  • 第二次握手:ack确保了接收方能收数据,syn确保了接收方能发数据
  • 第三次握手:确保了发送方能收数据
  • 四次握手浪费,两次握手不能保证“双方同时具备收发功能”

2、为什么客户端最后还要发送一次确认? 主要是为了防止已失效的连接请求报文段突然又传到了 服务器,因而产生错误。

3. TCP四次挥手

  • 主动关闭的一方发送FIN,表示要单方面关闭数据的传输

  • 服务端收到FIN后,发送一个ACK作为确认(序列号为收到的序列号 1)

  • 等服务器数据传输完毕,也发送一个FIN标识,表示关闭这个方向的数据传输

  • 客户端回复ACK以确认回复

    学新通

1、为什么挥手是四次而握手是三次?
TCP释放连接时之所以需要“四次挥手”,是因为FIN释放连接报文与ACK确认接收报文是分别由第二次和第三次"握手"传输的。为何建立连接时一起传输,释放连接时却要分开传输?

  • 建立连接时,被动方服务器端结束CLOSED阶段进入“握手”阶段并不需要任何准备,可以直接返回SYN和ACK报文,开始建立连接。
  • 释放连接时,被动方服务器,突然收到主动方客户端释放连接的请求时并不能立即释放连接,因为还有必要的数据需要处理,所以服务器先返回ACK确认收到报文,经过CLOSE-WAIT阶段准备好释放连接之后,才能返回FIN释放连接报文。

4. TCP可靠数据传输原理

(1) rdt1.0 协议

首先考虑最简单的情况,底层通信道是完全可靠的
学新通

  • 发送方

    • rdt_send(data):接收来自较高层的数据
    • make_pkt(data):产生一个包含该数据的分组
    • 将分组(packet)发送到信道中
  • 接收端

    • rdt_rcv:从底层信道接受一个分组
    • extract(packet, data):从分组中取出数据
    • deliver_data(data):将数据传给较高层

(2) rdt2.0 协议

第一种协议是在认为数据完全可靠下的情况,但是在实际模型中是分组中的比特可能受损的模型。
学新通

  • 发送方

    • 状态1:

      • 发送端协议等待来自上层传输下来的数据
      • rdt_send(data):接收来自较高层的数据,带有检验和
      • make_pkt(data):产生一个包含该数据的分组
      • udt_send(sndpkt):发送该分组
    • 状态2:

      • 等待来自接收方的ACK或NAK分组
      • rdt_rcv(rcvpkt) && isACK(rcvpkt):表示接收方已经正确接收分组,状态转换成等待上层调用
      • rdt_rcv(rcvpkt) &&isNAK(rcvpkt):表示上一个分组接收方的响应是重传,重新上传一遍分组并且等待和接收方回送的ACK和NAK
  • 接收方

    • 分组没有受损,返回ACK
    • 分组受损,返回NAK

(3) rdt2.1 协议

rdt2.0看似可以运行,但是有一个致命的缺陷,没有考虑到ACK或NAK受损的可能性。因此在rdt2.0基础上引入了序号。

发送方
学新通
接收方
学新通

(4)rdt 3.0

除了比特受损外,我们再考虑计算机网络中出现的底层信道丢包的情况。

设置一个倒技术定时器

  • 每次发送一个分组时便启动一个定时器
  • 响应定时器中断
  • 终止定时器

(5)流水线

rdt3.0是一个功能正确的传输协议,但是他的停等协议(等待接收方返回的ACK后才能进入等待上层调用的状态)的特殊性能也造成了效率较低的问题。

解决办法:不以停等的方式运行,允许发送方发送多个分组,无需等待确认。这种技术称为流水线
学新通

流水线带来的影响:

  • 必须增加序号范围,因为每个分组必须有唯一的标识符
  • 协议的发送发和接收方必须缓存多个分组
  • 所需序号范围对缓冲的要求取决于数据传输协议如何处理丢失、损坏以及延时过大的分组。解决流水线差错恢复的两种基本方法是:回退N步(GBN)和选择重传(SR)

(6)回退N步协议

回退N步协议(GBN协议,滑动窗口协议):允许发送发发送多个分组不需要等待确认,但是未确认的分组数不能超过某个最大值N。

设置N的原因:流量控制、拥塞控制

GBK协议响应的三种事件:

  • 发送方:

    • 当上层调用时

      • 窗口已满,告诉发送方等待一会
      • 窗口未满,产生一个分组并传送
    • 收到一个ACK

      • 窗口向右滑动
    • 超时事件

      • 如果收到一个ACK,但是前面的分组未被确认,重启定时器
  • 接收方:

    • 序号为n的分组被正确接收到,并且按序,为n发一个ACK
    • 其它所有情况,接收方丢弃该分组,并选择最近序列的分组重新发ACK

(8)选择重传协议(SR)

滑动窗口协议潜为了保证分组的正确顺序,对数据进行重传,但是考虑到窗口长度和带宽较大的情况,就会造成重复传递带来的效率问题。

选择重传:让发送发仅重传那些让它怀疑在接收方出错的分组,避免了不必要的重传。

(8)TCP中的可靠数据传输

因特网的网络层服务(IP服务)是不可靠的,即不保证数据交付、不保证数据包按序交付、不保证数据包的完整。TCP在IP不可靠尽力而为的服务至上创建了可靠数据传输服务,确保了数据传输到另一端的是无损坏、无间隙、非冗余且按序交付的。

我们将根据前面的原理来解释TCP如何实现可靠数据传输的:

  1. 如果来自下层的数据完全可靠,根据rdt1.0那么TCP协议只需要进行数据的传输即可。
  2. 但是很可惜,网络传输过程中往往有比特的损失,于是根据rdt2.0,加上了校验和确保了数据的正确性
  3. 看似上述协议已经完美,但是网络运输中还存在丢包的问题,根据rdt3.0,引入了计时器,当一个分组隔一段时间没有发过来,便重发一遍报文并重启计时器
  4. 但是计时器还存在一个问题,如果响应报文只是延迟传过来,怎么与其他报文进行区分呢?于是引入了序号。这样接收方就可以根据数据的字节编号,得出这些数据是接下来的数据,还是重传的数据。
  5. 根据rdt一些列的协议解决了可靠传输的问题,但是这是一种停等协议,就是说在传输的过程中,若未接收到报文的响应,上层应用就要一直等待,这样的工作效率太低。于是引入流水线的工作方式,运行多个报文发送,不用去等待响应报文后再继续发送。
  6. 网络中充斥着和发送数据包一样数据量的确认回复报文,因为每一个发送数据包,必须得有一个确认回复。提高网络效率的方法是:累积确认 。接收方不需要逐个进行回复,而是累积到一定量的数据包之后,告诉发送方,在此数据包之前的数据全都收到。例如,收到 1234,接收方只需要告诉发送方我收到4了,那么发送方就知道1234都收到了。
  7. 累计确认提高了网络效率,但是出现丢包的话采用的是GBN方法,即将从丢包的那个报文开始全部重传,这样做虽然保证了报文的有序性,但是一旦带框和流量大的话就会造成严重的资源浪费。所以在TCP报文的选项字段,可以设置已经收到的报文段,每一个报文段需要两个边界来进行确定。这样发送方,就可以根据这个选项字段只重传丢失的数据了。这种方法看起来很像SR协议,所以我们说TCP协议的可靠数据传输的差错恢复机制是GBN协议和SR协议的混合体。
  8. 发送是否可以无限发送直到把缓冲区所有数据发送完?不可以。因为需要考虑接收方缓冲区以及读取数据的能力。如果发送太快导致接收方无法接受,那么只是会频繁进行重传,浪费了网络资源。所以发送方发送数据的范围,需要考虑到接收方缓冲区的情况。这就是TCP的流量控制 。解决方法是:滑动窗口 。

5. TCP流量控制

对于发送端和接收端而言,TCP 需要把发送的数据放到发送缓存区, 将接收的数据放到接收缓存区。而流量控制要做的事情,就是在通过接收缓存区的大小,控制发送端的发送。如果对方的接收缓存区满了,就不能再继续发送了。

要具体理解流量控制,首先需要了解滑动窗口的概念。

TCP 滑动窗口分为两种: 发送窗口接收窗口

发送窗口

发送端的滑动窗口结构如下:

学新通

其中包含四大部分:

  • 已发送且已确认
  • 已发送但未确认
  • 未发送但可以发送
  • 未发送也不可以发送

其中有一些重要的概念,我标注在图中:

学新通

发送窗口就是图中被框住的范围。SND 即send, WND 即window, UNA 即unacknowledged, 表示未被确认,NXT 即next, 表示下一个发送的位置。

接收窗口

接收端的窗口结构如下:

学新通

REV 即 receive,NXT 表示下一个接收的位置,WND 表示接收窗口大小。

流量控制过程

6. TCP拥塞控制

上一节所说的流量控制发生在发送端跟接收端之间,并没有考虑到整个网络环境的影响,如果说当前网络特别差,特别容易丢包,那么发送端就应该注意一些了。而这,也正是拥塞控制需要处理的问题。

对于拥塞控制来说,TCP 每条连接都需要维护两个核心状态:

  • 拥塞窗口(Congestion Window,cwnd)
  • 慢启动阈值(Slow Start Threshold,ssthresh)

涉及到的算法有这几个:

  • 慢启动
  • 拥塞避免
  • 快速重传和快速恢复

接下来,我们就来一个一个地拆解这些状态和算法。首先,从拥塞窗口说起。

拥塞窗口

拥塞窗口(Congestion Window,cwnd)是指目前自己还能传输的数据量大小。

那么之前介绍了接收窗口的概念,两者有什么区别呢?

  • 接收窗口(rwnd)是接收端给的限制
  • 拥塞窗口(cwnd)是发送端的限制

限制谁呢?

限制的是发送窗口的大小。

有了这两个窗口,如何来计算发送窗口

发送窗口大小 = min(rwnd, cwnd)

取两者的较小值。而拥塞控制,就是来控制cwnd的变化。

慢启动

刚开始进入传输数据的时候,你是不知道现在的网路到底是稳定还是拥堵的,如果做的太激进,发包太急,那么疯狂丢包,造成雪崩式的网络灾难。

因此,拥塞控制首先就是要采用一种保守的算法来慢慢地适应整个网路,这种算法叫慢启动。运作过程如下:

  • 首先,三次握手,双方宣告自己的接收窗口大小
  • 双方初始化自己的拥塞窗口(cwnd)大小
  • 在开始传输的一段时间,发送端每收到一个 ACK,拥塞窗口大小加 1,也就是说,每经过一个 RTT,cwnd 翻倍。如果说初始窗口为 10,那么第一轮 10 个报文传完且发送端收到 ACK 后,cwnd 变为 20,第二轮变为 40,第三轮变为 80,依次类推。

难道就这么无止境地翻倍下去?当然不可能。它的阈值叫做慢启动阈值,当 cwnd 到达这个阈值之后,好比踩了下刹车,别涨了那么快了,老铁,先 hold 住!

在到达阈值后,如何来控制 cwnd 的大小呢?

这就是拥塞避免做的事情了。

拥塞避免

原来每收到一个 ACK,cwnd 加1,现在到达阈值了,cwnd 只能加这么一点: 1 / cwnd。那你仔细算算,一轮 RTT 下来,收到 cwnd 个 ACK, 那最后拥塞窗口的大小 cwnd 总共才增加 1。

也就是说,以前一个 RTT 下来,cwnd翻倍,现在cwnd只是增加 1 而已。

当然,慢启动拥塞避免是一起作用的,是一体的。

快速重传

在 TCP 传输的过程中,如果发生了丢包,即接收端发现数据段不是按序到达的时候,接收端的处理是重复发送之前的 ACK。

比如第 5 个包丢了,即使第 6、7 个包到达的接收端,接收端也一律返回第 4 个包的 ACK。当发送端收到 3 个重复的 ACK 时,意识到丢包了,于是马上进行重传,不用等到一个 RTO 的时间到了才重传。

这就是快速重传,它解决的是是否需要重传的问题。

选择性重传

那你可能会问了,既然要重传,那么只重传第 5 个包还是第5、6、7 个包都重传呢?

当然第 6、7 个都已经到达了,TCP 的设计者也不傻,已经传过去干嘛还要传?干脆记录一下哪些包到了,哪些没到,针对性地重传。

在收到发送端的报文后,接收端回复一个 ACK 报文,那么在这个报文首部的可选项中,就可以加上SACK这个属性,通过left edgeright edge告知发送端已经收到了哪些区间的数据报。因此,即使第 5 个包丢包了,当收到第 6、7 个包之后,接收端依然会告诉发送端,这两个包到了。剩下第 5 个包没到,就重传这个包。这个过程也叫做选择性重传(SACK,Selective Acknowledgment) ,它解决的是如何重传的问题。

快速恢复

当然,发送端收到三次重复 ACK 之后,发现丢包,觉得现在的网络已经有些拥塞了,自己会进入快速恢复阶段。

在这个阶段,发送端如下改变:

  • 拥塞阈值降低为 cwnd 的一半
  • cwnd 的大小变为拥塞阈值
  • cwnd 线性增加

应用层

应用层我们主要关注HTTP协议,HTTP使用TCP协议作为他的支撑运输协议

  • 客户发起一个与服务器的连接
  • 一旦连接建立,浏览器和服务器间的进程可以通过套接字接口来访问TCP
  • 客户通过套接字发送HTTP请求报文,从套接字接收HTTP响应报文
  • TCP提供可靠的数据传输服务
  • 服务器的响应报文完整的回到客户端

注意:HTTP是一个无状态协议,服务器向客户发送被请求的文件,不存储任何关于该客户的状态信息

1. HTTP报文格式

学新通

访问 hackr.jp 时,请求报文的首部信息

学新通

(1)HTTP请求报文

学新通

  • 请求行:请求方法 URI 协议版本

    • 请求方法:GET、POST、PUT、HEAD、OPTIONS、TRACT、CONNECT、LINK、UNLINK

      方法 说明 支持的HTTP版本
      Get 获取资源 1.0、1.1
      POST 传输实体主体 1.0、1.1
      PUT 传输文件 1.0、1.1
      HEAD 获取报文首部 1.0、1.1
      DELETE 删除文件 1.1
      OPTIONS 询问支持的方法 1.1
      TRACK 追踪路径 1.1
      CONNECT 要求使用隧道协议连接代理 1.1
      LINK 建立和资源之间的联系 1.0
      UNLINK 断开连接关系 1.0
    • URI
      学新通

      • 协议:http和https
      • 登录信息:可选,指定用户名和密码作为从服务器端获取资料的登录信息
      • 服务器地址:常见的URL,通过DNS解析成主机唯一的IP地址
      • 端口号:访问服务器的套接字,web服务器默认端口号是80
      • 带层次的文件路径:指定服务器上的特定文件路径获取资源
      • 查询字符:可选,对于已指定的文件路径内的资源可以使用查询字符串
      • 片段标识符:可选,标记出已获取资源中的子资源
    • 协议版本:http0.9、http1.0、http1.1

  • 首部字段:见下

  • 报文实体内容

2.HTTP响应报文

学新通

  • 状态行:协议版本 状态码 状态码的原因短语

    • 协议版本:http0.9、http1.0、http1.1

    • 状态码:
      学新通

      • 200 ok:正常处理了
      • 204 No Content:接受的请求已经成功处理,但是返回的响应报文中不含实体的主体部分
      • 206 Partial Content:该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求
      • 301 Moved Permanently:永久性重定向,表示请求得资源已经被分配了新的URI
      • 302 Found:临时性重定向,表示请求得资源已经分配了新的URI
      • 303 See Other:请求的资源存在着另一个URI,应使用GET方法定向获取请求的资源
      • 304 Not Modified:服务器允许访问资源,但是未满足条件的情况
      • 307 Temporary Redirect:临时重定向
      • 400 Bad Request:请求报文中存在着语法错误
      • 401 Unauthorized:需要有通过HTTP认真的认证信息
      • 403 Forbidden:请求资源被服务器拒绝了
      • 404 Not Found:服务器上无法找到请求的资源
      • 500 Internal Server Error:服务器在执行请求时出现了错误
      • 503 Service Unavailable:服务器超负荷或正在进行停机维护
  • 首部字段:见下

  • 主体

3.首部字段

  • 通用首部字段
    学新通
  • 请求首部字段
    学新通
  • 响应首部字段
    学新通
  • 实体首部字段
    学新通

2. get和post的区别

你敢在post和get上刁难我,就别怪我装逼了

  • get用来获取数据,post用来提交数据
  • get参数有长度限制(受限于url长度,具体的数值取决于浏览器和服务器的限制,最长2048字节),而post无限制。
  • get请求的数据会附加在url之 ,以 " ? "分割url和传输数据,多个参数用 "&"连接,而post请求会把请求的数据放在http请求体中。
  • get是明文传输,post是放在请求体中,但是开发者可以通过抓包工具看到,也相当于是明文的。
  • get请求会被浏览器主动cache,而post不会,除非手动设置。

3. 持续连接和非持续连接

从 Http0.9 到 Http2 要发送多个请求,从多个 Tcp 连接=>keep-alive=>管道化=>多路复用不断的减少多次创建 TCP 等等带来的性能损耗。

(1)非持续连接的HTTP

客户和服务器间的每一个请求/响应都用一个单独的TCP连接发送
学新通

缺点:

  • 必须为每一个请求对象建立一个全新的连接,客户和服务器中都要分配TCP缓冲区和保持TCP变量,给服务器带来严重负担
  • 每一个对象都要经受两倍RTT的交付时延,一个RTT用于建立TCP,一个用于请求和接收一个对象

(2)持续连接的HTTP

持久连接(HTTP Persistent Connections,也称HTTP keep-alive)

在采用HTTP1.1持续连接的情况下,服务器在发送响应后保持TCP连接的打开,后续的请求报文和响应报文能够通过相同的TCP连接进行传送。
学新通

管线化

持久的连接使得管线化成为可能——不需要等待下一个请求得到响应就可以进行下一次请求
学新通

多路复用

HTTP 传输是基于请求-应答的模式进行的,报文必须是一发一收,但值得注意的是,里面的任务被放在一个任务队列中串行执行,一旦队首的请求处理太慢,就会阻塞后面请求的处理。这就是著名的HTTP队头阻塞问题。

多路复用代替原来的序列和阻塞机制。所有就是请求的都是通过一个 TCP 连接并发完成。因为在多路复用之前所有的传输是基于基础文本的,在多路复用中是基于二进制数据帧的传输、消息、流,所以可以做到乱序的传输。多路复用对同一域名下所有请求都是基于流,所以不存在同域并行的阻塞。多次请求如下图:

学新通

4. http各版本的区别

HTTP各版本特性及区别

HTTP 1.0:

  • 任意数据类型都可以发送
  • 有GET、POST、HEAD三种方法
  • 无法复用TCP连接(长连接)
  • 有丰富的请求响应头信息。以header中的Last-Modified/If-Modified-SinceExpires作为缓存标识

HTTP 1.1:

  • 引入更多的请求方法类型PUTPATCHDELETEOPTIONSTRACECONNECT
  • 引入长连接,就是TCP连接默认不关闭,可以被多个请求复用,通过请求头connection:keep-alive设置
  • 引入管道连接机制,可以在同一TCP连接里,同时发送多个请求
  • 强化了缓存管理和控制Cache-ControlETag/If-None-Match
  • 支持分块响应,断点续传,利于大文件传输,能过请求头中的Range实现
  • 使用了虚拟网络,在一台物理服务器上可以存在多个虚拟主机,并且共享一个IP地址

HTTP 2:

  • 二进制分帧:不再是纯文本,避免文本歧义,缩小了请求体积
  • 服务器推送:服务器可以额外的向客户端推送资源,而无需客户端明确的请求
  • 多路复用: 在共享TCP链接的基础上同时发送请求和响应
  • 增加了安全性,使用HTTP 2.0,要求必须至少TLS 1.2
  • 使用HPACK算法将头部压缩,用哈夫曼编码建立索表,传送索引大大节约了带宽

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhbfgijk
系列文章
更多 icon
同类精品
更多 icon
继续加载