《计网:自顶向下》读书笔记(三)——运输层

3.1 概述和运输层服务

运输层协议为运行在不同主机上的应用进程之间提供了逻辑通信(logic communication)功能。
运输层协议是在端系统中而不是网络路由器中实现的。
在发送方,运输层将接受到的来自发送应用程序的报文转换成运输层分组,即运输层报文段(segment),然后运输层将这些报文段传递给传递给网络层。在接收方,网络层从数据报中提取运输层报文段,并将该报文段向上交给运输层,运输层则处理接收到的报文段,使得接收方应用进程可应用该报文段中的数据。

3.1.1 运输层和网络层的关系

在因特网协议栈中,运输层刚好位于网络层之上。运输层为运行在不同主机上的进程之间提供了逻辑通信,而网络层则提供了主机之间的逻辑通信。

3.1.2 因特网运输层概述

一般而言因特网是一个TCP/IP网络,为应用层提供了两种截然不同的运输层协议:UDP(用户数据报协议,为调用它的应用程序提供了一种不可靠的、无连接服务)和TCP(传输控制协议,为调用它的应用程序提供了一种可靠的面向连接的服务)。开发人员在创建套接字时必须制定是选择UDP还是选择TCP。
运输层报文段(segment)称为报文段。
因特网网络层协议有一个名字叫IP,全称是网际协议,IP为主机之间提供了逻辑通信。IP的服务模型是尽力而为交付服务(best-effort delivery service),所以IP被称为不可靠服务(unreliable service)
UDP与TCP最基本的任务是,将两个端系统间IP的交付服务扩展为运行在两个端系统上的进程之间的交付服务。将主机间交付扩展到进程间交付,称为运输层的多路复用(transport-layer multiplexing)多路分解(demultiplexing)
TCP为应用程序提供了几种附加服务:可靠数据传输(reliable data transfer)拥塞控制(congestion control)

3.2 多路复用与多路分解

作为网络应用的一部分,进程有一个或多个套接字(socket),它相当于从网络向进程传递数据和从进程向网络传递数据的门户。
将运输层报文段中的数据交付到正确的套接字的工作称为多路分解(demultiplexing)。从源主机的不同套接字中收集数据块,并为每个数据块封装上首部信息从而生成报文段,然后将报文段传递到网络层的工作称为多路复用(multiplexing)

3.3 无连接运输:UDP

UDP是一种无连接的运输层协议,因为在使用UDP时,在发送报文段之前,发送方和接收方的运输层实体之间没有进行握手。如果应用程序使用的运输层协议是UDP,则应用程序几乎是直接与IP打交道的。UDP从应用进程得到数据,附加上用于多路复用/分解服务的源端口号和目的端口号及长度和检验和(即报文段首部)形成报文段,然后将报文段交给网络层。网络层将该运输层报文段封装在IP数据报中,然后尽力而为的尝试将此报文段交付给接收主机。若该报文段到达接受主机,UDP使用目的端口号将报文段中的数据交付给正确的应用进程。
在进行UDP传输时,需要明确一个是发送端,一个是接收端:
UDP的发送端:

  1. 建立UDP的套接字服务,创建对象时如果没有明确端口,系统会自动分配一个未被使用的端口。
  2. 明确要发送的具体数据。
  3. 将数据封装成了数据包。
  4. 用套接字服务的send方法将数据包发送出去。
  5. 关闭资源。

UDP的接收端:

  1. 创建UDP的套接字服务,必须要明确一个端口,作用在于,只有发送到这个端口的数据才是这个接收端可以处理的数据。
  2. 定义数据包,用于存储接收到数据。
  3. 通过套接字服务的接收方法将收到的数据存储到数据包中。
  4. 通过数据包的方法获取数据包中的具体数据内容,比如ip、端口、数据等等。
  5. 关闭资源。

UDP的优势:

  1. 应用层能更好控制要发送的数据和发送时间。
  2. 无需连接建立。
  3. 无连接状态。
  4. 分组首部开销小。

SMTP->TCP;Telnet->TCP;HTTP->TCP;FTP->TCP;NFS->通常UDP;流式多媒体专用协议->UDP或TCP;因特网电话专用协议->UDP或TCP;SNMP->通常UDP;RIP->通常UDP;DNS->通常UDP。

3.3.1 UDP报文段结构

UDP的报文段结构分为UDP首部与数据字段,首部分为源端口号、目的端口号、长度和检验和,数据字段即来自应用层的报文。

3.3.2 UDP检验和

UDP检验和提供了差错检测功能,即检验和用于确定当UDP报文段从源达到目的地时,其中的比特是否发生了改变。

3.4 可靠数据传输的原理

数据可以通过一条可靠的信道进行传输(不会有传输数据比特收到损坏或丢失,而且所有数据都是按照其发送顺序进行传送的),实现这种服务抽象是可靠数据传输协议(reliable data transfer protocol)的责任。
以下所提到的是单向数据传输(unidirectional data transfer)即数据传输是从发送方到接收方的,可靠的双向数据传输(bidirectional data transfer)即双全工数据传输从概念上理解并不难。

3.4.1 构造可靠数据传输协议

  1. 完全可靠信道上的可靠数据传输:rdt1.0
    rdt的发送方只通过rdt_send(data)从较高层接收的数据,产生一个包含该数据的分组(经由make_pkt(data)动作),并将分组发送到信道中,rdt_send(data)事件是由较高层应用是过程调用(如rdt_send())产生的。在接收方,rdt通过rdt_rcv(packet)事件从底层信道接收一个分组,从分组中取出数据(经由extract(packet, data)动作),并将数据上传给较高层(通过deliver_data(data)动作),rdt_rcv(packet)事件是由较低层协议的过程调用(如rdt_rcv())产生的。
  2. 具有比特差错信道上的可靠数据传输:rdt2.0
    更现实的底层信道模型是分组中的比特可能受损。基于由接收方发送回确认是否正确收到的消息若否则需重传的机制的可靠数据传输协议称为自动重传请求(Automatic Repeat Request,ARQ)协议。ARQ中还需另外三种协议来处理比特差错:1)差错检测,2)接收方反馈,3)重传。还要考虑接收方的肯定/否定确认(ACK/NAK)报文是否受损(引入序号机制,表示接收方收到的反馈的状态码),还可以引入冗余ACK机制(接收方发送两次ACK报文代替发送NAK报文至发送方)。
  3. 具有比特差错的丢包信道上的可靠数据传输:rdt3.0
    除了比特受损外,底层信道还会丢包。引入定时器,发送方超时未收到非冗余ACK报文则重传。

3.4.2 流水线可靠数据传输协议

不是用停等方式运行,允许发送方可以在等待确认之前发送多个报文。因为从发送方向接收方输送的众多分组可以被看成是填充到一条流水线中,故这种技术称为流水线(pipelining)。解决流水线的差错恢复有两种基本办法:回退N步(Go-Back-N,GBN)选择重传(Selective Repeat,SR)

3.4.3 回退N步

当接收方检测到发送的序号不对时,要求发送方发送的序号从最后一个确认的编号开始,但是如果发送方的计时器超时,就要重发该帧与后面的N帧。

3.4.4 选择重传

有个窗口,当数据乱序到来的时候也不丢弃,先保存着,发送端的计时器就会超时,之后就会重新发送了。当接收到收到了重传分组那么滑动窗口就向后移。

3.5 面向连接的运输:TCP

3.5.1 TCP连接

TCP是面向连接(connection-oriented)的,这是因为在一个应用进程可以开始向另一个应用进程发送数据之前,这两个进程必须先相互“握手”,即它们必须相互发送某些预备报文段,以建立确保数据传输所需的参数。
TCP连接提供的是全双工服务(full-duplex service),也总是<stron>的。
TCP进行传输之间要进行三次握手建立连接,不需要传输的时候会进行四次挥手断开连接。
TCP可从缓存中取出并放入报文段中的数据数量受限于最大报文段长度(Maximum Segment Size,MSS)。MSS通常根据最初确定的最大链路层帧长度来设置,本地发送主机发送长度是这样的帧,即所谓最大传输单元(Maximum Transmission Unit,MTU),接着设置该MSS以保证一个TCP报文段(当封装在一个IP数据报中时)适合单个链路层帧。
TCP将客户机数据加一个TCP首部,从而形成了多个TCP报文段(TCP segment),这些报文段被下传给网络层,网络层将其分别封装在网络层IP数据报中。</stron>

3.5.2 TCP报文段结构

TCP报文段首部组成部分:

  1. 源端口号和目的端口号(source and destination port number):用于多路复用/多路分解来自或送至上层应用的数据;
  2. 检验和字段(checksum filed)
  3. 32比特的序号字段(sequence number field)和32比特的确认号字段(acknowledgement number filed):被TCP发送方和接收方用来实现可靠数据传输服务;
  4. 16比特的接收窗口(receive window)字段:用于流量控制;
  5. 4比特的首部长度字段(header length field):指示了以32比特的字为单位的TCP首部长度(由于TCP选项字段原因,TCP首部的长度是可变的,通常选项字段为空,所以一般TCP首部的长度就是20字节);
  6. 可选与变长的选项字段(flag field):用于当发送方与接收方协商最大报文段长度(MSS),或在高速网络环境下用作窗口调节因子时使用(首部字段中还定义了一个时间戳选项);
  7. 6比特的标志字段(flag field):ACK比特用于指示确认字段中的值是有效的(即该报文段包括一个对已被成功接受报文段的确认),RST、SYN和FIN比特用于连接建立和拆除,当PSH比特被设置时就指示接收方应立即将数据交给上层,URG比特用来指示报文段里存在着被发送方的上层实体置为“紧急”的数据(紧急数据的最后一个字节由16比特的紧急数据指针字段(urgent data pointer field)指出,当紧急数据存在并给出指向紧急数据尾的指针时TCP必须通知接收方的上层实体)。

3.5.3 往返时延的估计与超时

  1. 估计往返时延
    RTT表示从发送端发送数据开始,到发送端收到来自接收端的确认(接收端收到数据后便立即发送确认,不包含数据传输时间)总共经历的时延,由三个部分决定:链路的传播时延、末端系统的处理时延、路由器的缓存中的排队和处理时延。随着路由器的拥塞和端系统负载的变化,RTT估计值也会变化,一直刷新指数加权移动平均(Exponential Weighted Moving Average,EWMA)
  2. 设置和管理重传超时间隔
    根据RTT估计值而设置,波动较大时则大,波动较小时则小。

3.5.4 可靠数据传输

TCP发送方的三个与发送和重传有关的事件:

  1. TCP从上层应用程序接收数据,将数据封装在一个报文段中,然后交给IP。
  2. 超时后,TCP重传超时报文,然后,重启定时器。
  3. 收到ACK后,将其中确认号与发送方的最早未被确认的字节序号比较,若确认号大于最早未被确认的字节序号则在确认一个或多个先前未被确认的报文段且会更新最早未被确认的字节序号,反之重启定时器。

TCP重传:

  1. 由于确认报文丢失而重传
  2. 连续发送的报文段的确认报文延迟而先重传前一个
  3. 累计确认避免了第一个报文段的重传

TCP使用优雅的方式,每个发送方的重传都是经过越来越长的时间间隔后进行的。
超时重传存在的问题之一就是超时周期可能较长,当一个报文段丢失时,通过超时重传来恢复报文,就会增加端
到端的时延,但是可以通过检测收到的冗余ACK来进行对丢失报文段的重传。当发送方收到3个冗余ACK,就说明被确认过三次的报文段之后的那个报文段已经丢失,TCP就执行快速重传(fast retransmit),在丢失报文段定时器超时之前重传丢失报文段。
TCP的差错恢复机制为GBN协议和SR协议的混合体。

3.5.5 流量控制

TCP为应用程序提供了流量控制服务(flow-control service)以消除发送方使接收方缓存溢出的可能性,即让发送方的发送速率不要太快,要让接收方来得及接收。
TCP通过让发送方维护一个称为接收窗口(receive window)的变量来提供流量控制。接收窗口用于告诉发送方,该接收方还有多少可用的缓存空间。因为TCP是全双工通信,在连接两端的发送方都各自维护一个接收窗口。

3.5.6 TCP连接管理

TCP建立连接(三次握手)全过程:

  1. 客户端发送SYN给服务器,说明客户端请求建立连接;
  2. 服务端收到客户端发的SYN,并回复SYN+ACK给客户端(同意建立连接);
  3. 客户端收到服务端的SYN+ACK后,回复ACK给服务端(表示客户端收到了服务端发的同意报文);
  4. 服务端收到客户端的ACK,连接已建立,可以数据传输。

TCP建立连接要进行三次握手的原因:因为信道不可靠,而TCP想在不可靠信道上建立可靠地传输,那么三次通信是理论上的最小值;因为双方都需要确认对方收到了自己发送的序列号,确认过程最少要进行三次通信;为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

TCP释放连接(四次握手)全过程:

  1. 客户端发送FIN给服务器,说明客户端不必发送数据给服务器了(请求释放从客户端到服务器的连接);
  2. 服务器接收到客户端发的FIN,并回复ACK给客户端(同意释放从客户端到服务器的连接);
  3. 客户端收到服务端回复的ACK,此时从客户端到服务器的连接已释放(但服务端到客户端的连接还未释放,并且客户端还可以接收数据);
  4. 服务端继续发送之前没发完的数据给客户端;
  5. 服务端发送FIN+ACK给客户端,说明服务端发送完了数据(请求释放从服务端到客户端的连接,就算没收到客户端的回复,过段时间也会自动释放);
  6. 客户端收到服务端的FIN+ACK,并回复ACK给客户端(同意释放从服务端到客户端的连接);
  7. 服务端收到客户端的ACK后,释放从服务端到客户端的连接。

TCP释放连接要进行四次握手的原因:因为TCP是全双工模式,客户端请求关闭连接后,客户端向服务端的连接关闭(一二次挥手),服务端继续传输之前没传完的数据给客户端(数据传输),服务端向客户端的连接关闭(三四次挥手),所以TCP释放连接时服务器的ACK和FIN是分开发送的(中间隔着数据传输),而TCP建立连接时服务器的ACK和SYN是一起发送的(第二次握手),所以TCP建立连接需要三次,而释放连接则需要四次。
TCP 连接时可以ACK和SYN一起发送而释放时则ACK和FIN分开发送的原因:因为客户端请求释放时,服务器可能还有数据需要传输给客户端,因此服务端要先响应客户端FIN请求(服务端发送ACK),然后数据传输,传输完成后,服务端再提出FIN请求(服务端发送FIN);而连接时则没有中间的数据传输,因此连接时可以ACK和SYN一起发送。
客户端释放最后需要TIME-WAIT等待2MSL的原因:为了保证客户端发送的最后一个ACK报文能够到达服务端,若未成功到达,则服务端超时重传FIN+ACK报文段,客户端再重传ACK,并重新计时;防止已失效的连接请求报文段出现在本连接中,TIME-WAIT持续2MSL可使本连接持续的时间内所产生的所有报文段都从网络中消失,这样可使下次连接中不会出现旧的连接报文段。

3.6 拥塞控制原理

拥塞(congestion)现象是指到达通信子网中某一部分的分组数量过多,使得该部分网络来不及处理,以致引起这部分乃至整个网络性能下降的现象.

3.6.1 拥塞原因与开销

  1. 两个发送方和一个具有无穷大缓存的路由器:
    拥塞网络的一种开销,即当分组到达速率接近链路容量时,分组将经历较长的排队时延。
  2. 两个发送方和一个具有有限缓存的路由器:
    拥塞网络的另外一种开销,即发送方必须执行重传以补偿因为缓存溢出而丢弃(丢失)的分组。发送方在遇到大时延时所进行的不必要重传,导致路由器需要利用其链路带宽来转发不 必要的分组。
  3. 四个发送方、具有有限缓存的多台路由器和多跳路径:
    拥塞的另一种开梢,即当一个分组沿一条路径被丢弃时每个上游路由器用于转发该分组 而使用的传输容量最终被浪费掉了。

3.6.2 拥塞控制方法

  1. 端到端拥塞控制
  2. 网络辅助的拥塞控制

3.6.3 网络辅助的拥塞控制例子:ATM ABR拥塞控制

3.7 TCP拥塞控制

TCP发送方在感知拥塞时,为调节其发送速率采用了TCP拥塞控制算法(TCP congestion control algorithm),包括了三个部分:

  1. 加性增(additive-increase)乘性减(multiplicative-decrease)
    发送速率谨慎(线性)增加,折半减少。
  2. 慢启动(slow start)
    发送速率先指数增加,遇到第一个丢包时转为线性增加:超时事件发生后直接将发送速率降低为1个MSS然后指数增长、线性增长;收到3个冗余ACK后将发送速率减半然后线性增长。
  3. 对超时事件做出反应
    通过一个阈值来判断线性增长还是指数增长,通过遇超时事件或收到2、3个冗余ACK来决定阈值以及发送速率的改变。

高速网络下需要设计新的TCP。
TCP与UDP并发使用、TCP与并发TCP并发使用会产生不公平。

3.8 小结

TCP与UDP的区别:TCP面向连接,UDP是无连接的;TCP提供可靠的服务,也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达,UDP尽最大努力交付,即不保证可靠交付;TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道;每一条TCP连接只能是点到点的,UDP支持一对一,一对多,多对一和多对多的交互通信;TCP面向字节流(可能出现黏包问题),实际上是TCP把数据看成一连串无结构的字节流,UDP是面向报文的(不会出现黏包问题);UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等);TCP首部开销20字节;UDP的首部开销小,只有8个字节。
为使TCP实现面向连接可靠数据传输,TCP建立连接需要三次握手、关闭连接需要四次握手,需要差错恢复、估计往返时延、流量控制和拥塞控制机制。

博文补充(转):
一篇文章完全搞清楚scoket-read/write返回码、阻塞与非阻塞、异常处理
TCP keepalive的机理及使用
从TCP协议的原理来谈谈rst复位攻击
Linux的五种I/O模型
Linux下I/O多路复用的三种机制Select,Poll,Epoll
Linux的SIGPIPE信号产生原因与解决方法

全部评论

相关推荐

霁华Tel:秋招结束了,好累。我自编了一篇对话,语言别人看不懂,我觉得有某种力量在控制我的身体,我明明觉得有些东西就在眼前,但身边的人却说啥也没有,有神秘人通过电视,手机等在暗暗的给我发信号,我有时候会突然觉得身体的某一部分不属于我了。面对不同的人或场合,我表现出不一样的自己,以至于都不知道自己到底是什么样子的人。我觉得我已经做的很好,不需要其他人的建议和批评,我有些时候难以控制的兴奋,但是呼吸都让人开心。
点赞 评论 收藏
分享
2 收藏 评论
分享
牛客网
牛客企业服务