Bonky
Neither beliver nor reject anything, because any other person has rejected of believed it. Heaven has given you a mind for judging truth and error, Use it.
By Thomas Jefferson

计算机网络 – 数据传输层

概述

真正情况下,网络中进行通信的实体是在主机中的进程,是这台主机中的一个进程和另一台主机中的一个进程在交换数据(即通信)。

IP 协议虽然能把分组送到目的主机,但是这个分组还停留在主机的网络层而没有交付主机中的应用进程。从运输层的角度看,通信的真正端点并不是主机而是主机中的进程。也就是说,端到端的通信是应用进程之间的通信。

复用(multiplexing)和分用(也称解复用,demultiplexing):每个传输层段中都有一组信息,接收端主机传输层检查这些信息,将这些段直接传送给相应的socket,这个过程称为解复用 。在源端主机中,从不同的socket中将数据片收集起来,加上头部信息封装成段,并且将段传送给网络层称为复用

UDP socket需要两元组(目的主机IP地址和目的端口号),TCP socket需要四元组(源IP地址,源端口号,目的IP地址,目的端口号)

image-20190923081405223

运输层可以提供应用进程之间的逻辑通信”。“逻辑通信”的意思是:从应用层来看,只要把应用层报文交给下面的运输层运输层就可以把这报文传送到对方的运输层(即对应用层透明,提供一个黑盒的功能)。而网络层为主机之间提供逻辑通信。

拥塞控制

  • 开环控制:在网络系统设计时,事先就要考虑到有关发生拥塞的各种因素,力求在系统工作时不会出现拥塞。一旦整个系统启动并运行起来,就不再需要中途进行修改。开环控制手段可包括确定何时可接收新流量、确定何时可丢弃分组及丢弃哪些分组确定何种调度决策等。所有这些手段的共性是,在做决定时不考虑当前网络状态
  • 闭环控制:事先不考虑有关发生拥塞的各种因素,采用验杀统去监视,即时检测到哪里发生拥塞(就像道路上的摄像头,看到哪里发生堵车,立刻派交警去解决),然后将拥塞信息传到合适的地方以便调整系统运行,改正问题。其主要措施包括检测拥塞、报告拥塞和

调整措施。

TCP和UDP

按照 OSI 的术语,两个对等运输实体在通信时传送的数据单位叫做运输协议数据单元 TPDU (Transport Protocol Data Unit)。但在TCP/IP体系中,则根据所使用的协议是TCP UDP,分别称之为 TCP 报文段(segment)或 UDP 用户数据报。

UDP 在传送数据之前不需要先建立连接。远地主机的运输层在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但在某些情况下 UDP 却是一种最有效的工作方式。

TCP 则提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。TCP 不提供广播或多播服务。由于 TCP 要提供可靠的、面向连接的运输服务,因此不可避免地增加了许多的开销,如确认、流量控制、计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多的处理机资源。

image-20190923083213666

注意TCP面向字节流,而UDP面向报文流:在报文流中,网络保持对报文边界的跟踪:而在字节流中,网络不作这样的跟踪。

例如,一个进程向一条连接写了 1024 B,稍后又写了 1024 B,那么接收方共读了 2048 B。对于报文流,接收方将得到两个报文,每个报文 1024 B。而对于字节流,报文边界不被识别,接收方将全部 2048 B 当作一个整休在此己经体现不出原先有两个不同报文。

的事实。

端口

协议端口号Protocol port number,一般称作端口,作用是为了网络层的分用设置的,用来区分各应用进程。

请注意,这种在协议栈层间的抽象的协议端口是软件端口,和硬件端口是完全不同的概念。硬件端口是不同硬件设备进行交互的接口 (如USB端口等等),而软件端口是应用层的各种协议进程与运输实体进行层间交互的一种地址。不同的系统具体实现端口的方法可以是不同的(取决于系统使用的操作系统)。

TCP/IP的运输层用一个16位端口号来标志一个端口。16 位的端口号可允许有 655355 个不同的端口号,这个数目对一个计算机来说是足够用的。

服务器端使用的端口号一共分为两类。最重要的一类叫做熟知端口号well known port number)或系统端口号,数值为1~1023。表 5-2 给出了一些常用的熟知端口号。

image-20190923085754670

另一类叫做登记端口号,数值为 1024~49151。这类端口号是为没有熟知端口号的应用程序使用的。使用这类端口号必须在 IANA 按照规定的手续登记,以防止重复。比如QQ的登记端口号为4000

屏幕快照 2019-09-23 上午9.11.28

具体可以在这查到:Service Name and Transport Protocol Port Number Registry

客户端使用的端口号数值为 49152~65535。由于这类端口号仅在客户进程运行时才动态选择,因此又叫做短暂端口号。这类端口号留给客户进程选择暂时使用。当服务器进程收到客户进程的报文时,就知道了客户进程所使用的端口号,因而可以把数据发送给客户进程。通信结束后,刚才已使用过的客户端口号就不复存在,这个端口号就可以供其他客户进程使用。

UDP协议

概述

用户数据报协议 UDP 只在 IP 的数据报服务之上增加了复用和分用以及差错检测的功能。UDP 的主要特点是:

  1. UDP 是无连接的,即发送数据之前不需要建立连接(当然,发送数据结束时也没有连接可释放),因此减少了开销和发送数据之前的时延。
  2. UDP 使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态表(这里面有许多参数)。
  3. UDP 是面向报文的。发送方的 UDP 对应用程序交下来的报文,在添加首部后就向下交付 IP 层。这就是说,应用层交给 UDP 多长的报文,UDP 就照样发送,即一次发送一个报文。也就是说,UDP 一次交付一个完整的报文。因此,应用程序必须选择合适大小的报文。若报文太长,UDP 把它交给 IP 层后,IP 层在传送时可能要进行分片,这会降低 IP 层的效率。反之,若报文太短,UDP 把它交给 IP 层后,会使 IP 数据报的首部的相对长度太大,这也降低了 IP 层的效率。
  4. UDP 没有拥塞控制,因此网络出现的拥塞不会使源主机的发送速率降低。导致UDP 的延迟偏低
  5. UDP 支持一对一、一对多、多对一和多对多的交互通信
  6. UDP 的首部开销小,只有 8 个字节,比 TCP 的 20 个字节的首部要短。

UDP的首部

屏幕快照 2019-09-23 上午10.41.44

如果接收方 UDP 发现收到的报文中的目的端口号不正确(即不存在对应于该端口号的应用进程),就丢弃该报文,并由网际控制报文协议 ICMP 发送“端口不可达”差错报文给发送方。

UDP 用户数据报首部中检验和的计算方法有些特殊。在计算检验和时,要在 UDP 用户数据报之前增加 12 个字节的伪首部。所谓“伪首部”是因为这种伪首部并不是 UDP 用户数据报真正的首部。只是在计算检验和时,临时添加在 UDP 用户数据报前面,得到一个临时的 UDP 用户数据报。检验和就是按照这个临时的 UDP 用户数据报来计算的。UDP 计算检验和的方法类似于 IP 数据报首部检验和的方法。但不同的是:IP 数据报的检验和只检验 IP 数据报的首部,但 UDP 的检验和是把首部和数据部分一起都检验。

image-20190923133744275

UDP的优势

转自:https://blog.wilddog.com/?p=668

随着网络技术飞速发展,网速已不再是传输的瓶颈,UDP协议以其简单、传输快的优势,在越来越多场景下取代了TCP,如网页浏览、流媒体、实时游戏、物联网。

网速的提升给UDP稳定性提供可靠网络保障

网络环境变好,网络传输的延迟、稳定性也随之改善,UDP的丢包率低于5%,如果再使用应用层重传,能够完全确保传输的可靠性。

对比测试结果UDP性能优于TCP

为了提升浏览速度,Google基于TCP提出了SPDY协议以及HTTP/2GoogleChrome上实验基于UDPQUIC协议,传输速率减少到100ms以内。

1

Google采用QUIC后连接速率能有效提升75%。
Google搜索采用QUIC后页面加载性能提升3%。
YouTube采用QUIC后重新缓冲次数减少了30%。

TCP设计过于冗余,速度难以进一步提升

TCP为了实现网络通信的可靠性,使用了复杂的拥塞控制算法,建立了繁琐的握手过程以及重传策略。由于TCP内置在系统协议栈中,极难对其进行改进。

UDP协议越来越多场景下取代了TCP

网页浏览

使用UDP协议有三个优点 :

  • 能够对握手过程进行精简,减少网络通信往返次数;
  • 能够对TLS加解密过程进行优化;
  • 收发快速,无阻塞。

流媒体

采用TCP,一旦发生丢包,TCP会将后续包缓存起来,等前面的包重传并接收到后再继续发送,延迟会越来越大。基于UDP的协议如WebRTC是极佳的选择。

实时游戏

对实时要求较为严格的情况下,采用自定义的可靠UDP协议,比如EnetRakNet(用户有sony online game,minecraft)等,自定义重传策略,能够把丢包产生的延迟降到最低,尽量减少网络问题对游戏性造成的影响。采用UDP的经典游戏如FPS游戏Quake、CS,著名的游戏引擎Unity3D采用的也是RakNet。

采用UDP有3个关键点

  • 网络带宽需求较小,而实时性要求高;
  • 大部分应用无需维持连接;
  • 需要低功耗。

TCP协议

特点

  • TCP 是面向连接的运输层协议。这是说应用进程之间的通信好像在“打电话”,通话前要先拨号建立连接,通话结束后要挂机释放连接。
  • 每一条 TCP 连接只能有两个端点
  • TCP 提供可靠交付的服务。通过 TCP 连接传送的数据,无差错、不丢失、不重复,并且按序到达。
  • TCP 提供全双工通信。TCP 允许通信双方的应用进程在任何时候都能发送数据。TCP 连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据。在发送时,应用程序在把数据传送给 TCP 的缓存后,就可以做自己的事,而 TCP 在合适的时候把数据发送出去。在接收时,TCP 把收到的数据放入缓存,上层的应用进程在合适的时候读取缓存中的数据。
  • 面向字节流。UDP是面向报文的。UDP对于发送方应用层交下来的报文,不合并,不拆分,只是在其上面加上首部后就交给了下面的网络层,也就是说无论应用层交给UDP多长的报文,它统统发送,一次发送一个。而对接收方,接到后直接去除首部,交给上面的应用层就完成任务了。因此,它需要应用层控制报文的大小。而TCP是面向字节流的,它把上面应用层交下来的数据看成无结构的字节流来发送,可以想象成流水形式的,发送方TCP会将数据放入“蓄水池”(缓存区),等到可以发送的时候就发送,不能发送就等着,TCP会根据当前网络的拥塞状态来确定每个报文段的大小。

image-20190929232855083

TCP的连接

前面已经讲过,每一条 TCP 连接有两个端点。TCP 连接的端点是叫做套接字(Socket)或插口。Socket·的表示方法是 IP 地址后面写上端口号,中间用冒号或逗号隔开:socket= (IP :Port)。其中,每个TCP 连接可表示为:TCP连接 ::= {socket1, socket2} = {(IP1: port1), (IP2: port2)}

TCP报文的首部

TCP 报文段首部的前 20 个字节是固定的,后面有 4n 字节是根据需要而增加的选项。因此 TCP 首部的最小长度是 20 字节。

image-20190930085227067

  • 源端口和目的端口各占 2 个字节
  • 序号(seq)占 4 字节。共 4294967296个序号。TCP 是面向字节流的。传送每一个字节都按顺序编号。 整个要传送的字节流的起始序号必须在连接建立时设置。首部中的序号字段值则指的是本报文段所发送的数据的第一个字节的序号。例如,一报文段的序号字段值是 301, 而携带的数据共有 100 字节。这就表明:本报文段的数据的第一个字节的序号是 301, 最后一个字节的序号是 400。显然,下一个报文段(如果还有的话)的数据序号应当从 401 开始,即下一个报文段的序号字段值应为 401。这个字段的名称也叫做“报文段序号”。
  • 确认号(ack)占 4 字节,是期望收到对方下一个报文段的第一个数据字节的序号。若确认号=N,则表明:到序号 N-1 为止的所有数据都已正确收到。
  • 数据偏移占 4 位,它指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远。这个字段实际上是指出 TCP 报文段的首部长度。
  • 保留占 6 位,保留为今后使用,但目前应置为 0。
  • 控制位占六位,用来说明本报文段的性质。
    • 紧急 URG。当 URG=1 时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,于是发送方 TCP 就把紧急数据插入到本报文段数据的最前面。
    • 确认 ACK。仅当 ACK=1 时确认号字段才有效。当 ACK=0 时,确认号无效。在连接建立后所有传送的报文段 ACK 都为 1。
    • 推送 PSH。 当两个应用进程进行交互通信时,有时在一端的应用进程希望在键入一个命令后立即就能够收到对方的响应。在这种情况下,TCP 就可以使用推送操作。接收方 TCP 收到 PSH=1 的报文段,就尽快地交付接收应用进程,而不再等到整个缓存都填满了后再向上交付。
    • 复位 RST。 当 RST=1 时,表明 TCP 连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。
    • 同步 SYN。 在连接建立时用来同步序号。当 SYN=1 而 ACK =0 时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应的报文段中使 SYN=1 和 ACK =1,表示这是一个连接接受报文。
    • 终止 FIN。 来释放一个连接。当 FN=1 时,表明此报文段的发送方的数据已发送完毕,并要求释放运输连接。
  • 窗口占 2 字节。窗口值告诉对方:从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量(以字节为单位)。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。总之,窗口值作为接收方让发送方设置其发送窗口的依据。窗口字段明确指出了现在允许对方发送的数据量。窗口值经常在动态变化着。
  • 检验和占 2 字节。
  • 紧急指针占 2 字节。紧急指针仅在 URG=1 时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结東后就是普通数据)。值得注意的是,即使窗口为零时也可发送紧急数据。
  • 选项 长度可变,最长可达 40 字节

三次握手🤝四次挥手👋🏻

20180717202520531

3 次握手的目的很简单,就是分配资源,初始化序列号

第一次握手:建立连接时,客户端发送syn包(syn=x)到服务器,并进入SYN_SENT状态,等待服务器确认。

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

20180717204202563

4 次挥手的目的是终止数据传输,并回收资源,必须等待两方向都没有数据传输时才能拆除虚链路

第一次挥手:客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。

第二次挥手:服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。

客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。

第三次挥手:服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为 seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。

第四次挥手:客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是 seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2^MSL^(最长报文段寿命)的时间后,当客户端撤销相应的TCB(传输控制模块)后,才进入CLOSED状态。

服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

可靠传输

停止等待协议

image-20190930082612092

无差错情况

图 (a)是最简单的无差错情况。A 发送分组 M1, 发完就暂停发送,等待 B 的确认。B 收到了 M1 就向 A 发送确认。A 在收到了对 M1 的确认后,就再发送下一个分组 M2。

出现差错:

图(b)是分组在传输过程中出现差错的情况。B 接收 M1 时检测出了差错,就丢弃 M1, 其他什么也不做(不通知 A 收到有差错的分组)。也可能是 M1 在传输过程中丢失了,这时 B 当然什么都不知道。在这两种情况下,B 都不会发送任何信息。A 只要超过了一段时间仍然没有收到确认,就认为刚才发送的分组丢失了,因而重传前面发送过的分组。这就叫做超时重传。要实现超时重传,就要在每发送完一个分组时设置一个超时计时器。如果在超时计时器到期之前收到了对方的确认,就撤销已设置的超时计时器。其中我们需要注意

  • A 必须暂时保留已发送的分组的副本,只有在收到相应的确认后才能清除暂时保留的分组副本。

  • 分组和确认分组都必须进行编号。这样才能明确是哪一个发送出去的分组收到了确认,而哪一个分组还没有收到确认。

  • 超时计时器设置的重传时间应当比数据在分组传输的平均往返时间更长一些。

确认丢失和确认迟到:

image-20190930083249703

上图(a)说明的是另一种情况。B 所发送的对 M1 的确认丢失了。A 在设定的超时重传时间内没有收到确认,并无法知道是自己发送的分组出错、丢失,或者是 B 发送的确认丢失了。因此 A 在超时计时器到期后就要重传 M1。现在应注意 B 的动作。假定 B 又收到了重传的分组 M1。这时应采取两个行动

  1. 丢弃这个重复的分组 M1, 不向上层交付。
  2. 向 A 发送确认。不能认为已经发送过确认就不再发送,因为 A 之所以重传 M1 就表示 A 没有收到对 M1 的确认。

图(b)也是一种可能出现的情况。传输过程中没有出现差错,但 B 对分组 M1 的确认迟到了。A 会收到重复的确认。对重复的确认的处理很简单:收下后就丢弃。B 仍然会收到重复的 M1, 并且同样要丢弃重复的 M1,并重传确认分组

通常 A 最终总是可以收到对所有发出的分组的确认。如果 A 不断重传分组但总是收不到确认,就说明通信线路太差,不能进行通信。

像上述的这种可靠传输协议常称为自动重传请求 ARQ (Automatic Repeat request)。意思是重传的请求是自动进行的。接收方不需要请求发送方重传某个出错的分组。

信道利用率:

信道的利用率是通信的一个很重要的的指标

image-20190930084214495

其中信道的利用率计算式如下。
U=\frac{T_{D}}{T_{D}+\mathrm{RTT}+T_{A}}
可以看出停止等待协议的信道利用率太低,为了提高传输效率,发送方可以不使用低效率的停止等待协议,而是采用流水线传输。流水线传输就是发送方可连续发送多个分组,不必每发完一个分组就停下来等待对方的确认。常见的有连续 ARQ 协议和滑动窗口协议

image-20190930084837383

连续ARQ协议

连续 ARQ 协议规定,发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置。

屏幕快照 2019-10-23 上午8.34.24

累积确认有优点也有缺点。优点是:容易实现,即使确认丢失也不必重传。但缺点是不能向发送方反映出接收方已经正确收到的所有分组的信息。

例如,如果发送方发送了前 5 个分组,而中间的第 3 个分组丢失了。这时接收方只能对前两个分组发出确认。发送方无法知道后面三个分组的下落,而只好把后面的三个分组都再重传一次。这就叫做 Go-back-N(回退 N),表示需要再退回来重传已发送过的 N 个分组。可见当通信线路质量不好时,连续 ARQ 协议会带来负面的影响。

实现可靠传输

滑动窗口

一个直观的理解,一定要先看看这个哈哈哈哈:TCP协议的滑动窗口具体是怎样控制流量的? – 安静的木小昊的回答 – 知乎 https://www.zhihu.com/question/32255109/answer/495373328

屏幕快照 2019-10-23 下午7.43.02

在没有收到 B 的确认的情况下,A 可以连续把窗口内的数据都发送出去。凡是已经发送过的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用。窗口越大,发送方就可以在收到对方确认之前连续发送更多的数据。

videoplayback

超时重传时间的选择

TCP 采用了一种自适应算法,它记录一个报文段发出的时间,以及收到相应的确认的时间。这两个时间之差就是报文段的往返时间 RTT​。TCP 保留了 RTT 的一个加权平均往返时间 RTTs​ 因为进行的是加权平均,因此得出的结果更加平滑)。每当第一次测量到 RTT 样本时,RTTs​ 值就取为所测量到的 RTT 样本值。但以后每测量到一个新的 RTT 样本,就按下式重新计算一次 RTTs:

显然,超时计时器设置的超时重传时间 RTO (Retransmissiontime-Out)应略大于上面得出的加权平均往返时间 RTTs。RFC6298 建议使用下式计算 RTO:

其中 RTTD 是 RTT 的偏差的加权平均值,它与 RTTs 和新的 RTT 样本之差有关。RFC 6298 建议这样计算 RTTD。当第一次测量时,RTTD 值取为测量到的 RTT 样本值的一半。在以后的测量中,则使用下式计算加权平均的 RTTD。

这里 β 是个小于 1 的系数,它的推荐值是 0.25。

但是,若收到的确认是对重传报文段的确认,但却被源主机当成是对原来的报文段的确认,则这样计算出的 RTTs 和超时重传时间 RTO 就会偏大。若后面再发送的报文段又是经过重传后才收到确认报文段,则按此方法得出的超时重传时间 RTO 就越来越长。

同样,若收到的确认是对原来的报文段的确认,但被当成是对重传报文段的确认,则由此计算出的 RTTs 和 RTO 都会偏小。这就必然导致报文段过多地重传。这样就有可能使 RTO 越来越短。

Share

You may also like...

发表评论

电子邮件地址不会被公开。 必填项已用*标注