zoukankan      html  css  js  c++  java
  • 【计算机网络】传输层

    运输层和网络层的区别:

    • 网络层: 不同主机之间的逻辑通信
    • 运输层: 应用进程之间的逻辑通信

    类似于家庭间通信:
    A家庭的12个孩子要与B家庭的12个孩子相互通信

    • 进程 = 孩子们
    • 进程间报文 = 信封中的信笺
    • 主机 = 家庭的房子
    • 运输协议 = A -> B
    • 网络层协议 =
      • Home of A->Home of B
      • 邮局提供的服务

    服务

    功能

    从通信和信息处理的角度看,传输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能中的最底层。为运行在不同主机上的进程之间提供了逻辑通信

    网络的边缘部分的两台主机使用网络核心部分的功能进行端到端的通信时,只有主机的协议栈才有传输层和应用层,而路由器在转发分组时都只用到下三层的功能(即 在通信子网中没有传输层,传输层只存在于通信子网以外的主机中)。

    • 传输层提供应用层之间的逻辑通信(即 端到端的通信)。与网络层的区别是,网络层提供的是主机之间的逻辑通信。

      逻辑通信:传输层之间的通信好像是沿水平方向传送数据,但事实上这两个传输层之间并没有一条水平方向的物理连接。

    • 复用和分用。
      • 复用:(多个进程→一段数据)是指发送方不同的应用进程都可使用同一个传输层协议传送数据;
      • 分用:(一段数据→多个进程)是指接收方的传输层在剥去报文的首部后能够把这些数据正确交付到目的应用进程

        注意:传输层的复用分用功能与网络层的复用分用功能不同。
        网络层复用是指发送方不同协议的数据都可以封装成IP数据报发送出去,分用是指接收方的网络层在剥去首部后把数据交付给相应协议。

    • 传输层还要对收到的报文进行差错检测(首部和数据部分)。而网络层只检查IP数据报的首部,不检验数据部分是否出错。
    • 提供两种不同的传输协议,即 面向连接的TCP和无连接的UDP。而网络层无法同时实现两种协议(即 在网络层要么只提供面向连接的服务,如虚电路;要么只提供无连接服务,如数据报,而不可能在网络层同时存在这两种方式

      TCP和UDP分别拥有自己的端口号,它们互不干扰,可以同时实现。

    传输层向高层用户屏蔽了低层网络核心的细节(如网络拓扑、路由协议等),它使应用进程看见的是好像在两个传输层实体之间有一条端到端的逻辑通信信道,这条通信信道对上层的表现却因传输层协议不同而有很大的差别。
    TCP时,尽管下面的网络是不可靠的,当这种通信信道就相当于一条全双工的可靠信道。
    UDP时,这种逻辑通信信道仍然是一条不可靠信道。

    端口

    原本进程是用进程标识符来标志的。但运行在应用层的各种应用程序却不应当让计算机操作系统指派它的进程标识符,往往需要利用目的主机提供的功能来识别终点,而不需要知道实现这个功能的进程。

    • 协议端口号(Protocol port number),通常简称为端口(port)。

      注意与路由器的物理端口区分。

    • 端口是传输层的服务访问点(TSAP),用来表示主机中的应用进程。(数据链路层的SAP是MAC地址,网络层的SAP是IP地址,用来标识主机)

      服务访问点(service access point, SAP):实际就是逻辑接口,是一个层次系统的上下层之间进行通信的接口,N层的SAP就是N+1层可以访问N层服务的地方。

    • 特点:
      • 应用进程通过端口号进行标识
      • 端口用一个16位端口号进行标志。
      • 端口号只具有本地意义,即 端口号只是为了标志本计算机应用层中的各进程。在互联网中,不同计算机的相同端口号是没有联系的

        由此可见,两个计算机中的进程要互相通信,不仅必须知道对方的IP地址(为了找到对方的计算机),而且还要知道对方的端口号(为了找到对方计算机中的应用进程)。

    • 分类:
      • 服务器端使用的端口号:(固定,对应一个进程)
        • 熟知端口号:数值为0~1023。IANA(互联网地址指派机构)把这些端口号指派给了TCP/IP最重要的一些应用程序,让所有的用户都知道。
        • 登记端口号:数值为1024~49151。它是供没有熟知端口号的应用程序使用的,使用这类端口号必须再IANA登记,以防止重复。
      • 客户端使用的端口号:(不固定,系统指派,不对应某个固定的进程)
        • 又称为短暂端口号,数值为49152~65535。留给客户进程选择暂时使用
        • 当服务器进程收到客户进程的报文时,就知道了客户进程所使用的动态端口号。通信结束后,这个端口号可供其他客户进程以后使用。
    • 套接字:

      在网络中通过IP地址来标识和区别不同的主机,通过端口号来标识和区分一台主机中的不同应用进程。在网络中采用发送方和接收方的套接字(Socket)组合来识别端点

    • 所谓套接字,实际上是一个通信端点,即 套接字=(主机IP地址,端口号)

      套接字的长度为48位32位IP地址+16位端口号

    • 它唯一地标识网络中的一台主机和其上的一个应用(进程)。

      进程通过套接字来接收和发送报文,套接字相当于一个通道。

    • 常用的熟知端口:

      协议 应用程序 名称 端口号
      UDP RPC 实时传输协议 111
      DNS 域名系统 53
      DHCP 动态主机设置协议 67,68
      TFTP 简单文件传输协议 69
      SNMP 简单网络管理协议 161
      SNMP(trap) 162
      TCP SMTP 简单邮件传输协议 25
      POP 邮局协议 110
      FTP 文件传输协议 21,20
      Telent 远程终端协议 23
      HTTP 超文本传输协议 80
      HTTPS 超文本传输安全协议 443
    • 无连接服务与面向连接服务:
      • 无连接服务:是指两个实体之间的通信不需要先建立好连接,需要通信时,直接将信息发送到“网络”中,让该信息的传递在网上尽力而为地往目的地传送。

        无连接的用户数据报协议(UDP),传输层向上提供的是一条不可靠的逻辑信道。由于UDP比较简单,因此执行速度比较快、实时性好,主要用于小文件传送协议(TFTP)、DNS、SNMP和实时传输协议(RTP)。

      • 面向连接服务:是指在通信双方进行通信之前,必须先建立连接,在通信过程中,整个连接的情况一直被实时地监控和管理。通信结束后,应该释放这个连接。

        面向连接的传输控制协议(TCP),传输层向上提供的是一条全双工的可靠逻辑信道。主要适用于可靠性更重要的场合,如文件传输协议(FTP)、超文本传输协议(HTTP)、远程登录(TELENT)等。
        注意:虽然连接→可靠,但是可靠≠连接“可靠”指的是使用确认机制来确保传输的数据不丢失。

    UDP协议

    RFC768定义的用户数据报协议(UDP,User Datagram Protocol)只是做了传输协议能够做的最少工作,它仅在IP的数据报服务之上增加了两个最基本的服务:复用和分用以及差错检测

    • 特点:
      • 无连接
      • 尽最大努力交付
      • 面向报文。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。UDP一次交付一个完整的报文

        因此报文不可分割,是UDP数据报处理的最小单位。

      • 发送的是UDP数据报,即 一个完整的报文
      • 没有拥塞控制。因此网络出现的拥塞不会是源主机的发送速率降低。则对某些实时应用是很重要的,很适合多媒体通信的要求。
      • 支持一对一一对多多对一多对多
      • 首部开销小,只有8个字节,比TCP20个字节首部要短

    UDP数据报

    • 首部格式:(8B的固定首部)
    • (伪首部):这个其实是不存在的,只是在计算校验和时临时添加的,用于给“检验和”进行校验。(UDP和TCP都有
    • 源端口:2字节。源端口号。
    • 目的端口:2字节。目的端口号。
    • 长度:2字节,单位为1B。UDP数据报的长度(包括首部和数据),其最小值是8(仅有首部)。
    • 校验和:2字节。检测UDP数据报在传输中是否有错,有错就丢弃。(二进制反码运算求和再取反)

      注意:检验和字段是可选的,当源主机不想计算校验和,则直接令该字段全为0.(校验时计算出则16位字的和,无差错时结果应全为1(因为校验和是它们和的反码,所以加上校验位应该要全为1))
      二进制反码求和:规则是从低到高位逐列进行计算。0和0加得0,0和1加得1,1和1加得0但要产生一个进位1,加到下一列。若最高位产生了进位,则最后得到的结果要加1

    TCP协议

    传输控制协议(TCP,Transmission Control Protocol)是在不可靠的IP层之上实现的可靠的数据传输协议,它主要解决传输的可靠、有序、无丢失和不重复问题。

    • 特点:
      • 面向连接
      • 只能一对一。每一条TCP连接只能有两个端点(endpoint),每一条TCP连接只能是点对点的。
      • 可靠交付
      • 全双工通信
      • 面向字节流:虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序交下来的数据看成仅仅是一连串无结构的字节流

        TCP中的“流”(stream)指的是流入或流出进程的字节序列。

    TCP报文段

    TCP报文段既可以用来运载数据,又可以用来建立连接、释放连接和应答。(TCP也有伪首部,但此处不写

    • 首部格式:(20B的固定首部)
    • 源端口:占2字节。端口是运输层与应用层的服务接口。运输层的复用和分用功能都要通过端口才能实现。
    • 目的端口:占2字节。
    • 序号字段(seq)(SEQuence):占4字节。TCP连接中传送的数据流中的每一个字节都编上一个序号。序号字段的值则指的是本报文段所发送的数据的第一个字节在整个报文字节流中的序号。
    • 确认号字段(ack):占4字节。期望收到对方的下一个报文段的数据的第一个字节的序号。
    • 数据偏移(即 首部长度):占4bit,单位为4B,指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。单位为32bit(以4B为计算单位)(如数据偏移=15时,首部长度=15*4B=60B)

    • 保留字段:占6bit。保留为今后使用,但目前应置为0。

    • 紧急位URG(URGent):占1bit。当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送。(一般不使用)

    • 确认位ACK(ACKnowledgement):占1bit。只有当ACK=1时确认号字段才有效。当ACK=0时,确认号无效。

    • 推送位PSH(PuSH):占1bit。接收TCP收到推送比特置1的报文段,就尽快地交付给接收应用进程,而不再等到整个缓存都填满了后再向上交付。

    • 复位位RST(ReSeT):占1bit。当RST=1时,表明TCP连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。

    • 同步位SYN(SYNchronization):占1bit。指我要进行同步连接了,同步SYN=1,就表示这是一个连接请求连接接收报文
      • SYN=1,ACK=0时,连接请求报文
      • SYN=1,ACK=1时,连接接受报文
    • 终止位FIN (FINal):占1bit。用来释放一个连接。当FIN=1时,表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。

    • 窗口字段:占2字节。窗口字段用来控制对方发送的数据量,单位为字节。TCP连接的一端根据设置的缓存空间大小确定自己的接收窗口大小,然后通知对方以确定对方的发送窗口的上限。

    • 校验和:占2字节。检验和字段检验的范围包括首部和数据这两部分。在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。

    • 紧急指针字段:占16bit。紧急指针指出在本报文段中的紧急数据的最后一个字节的序号。


    • 选项字段(长度可变):TCP只规定了一种选项,即最大报文段长度MSS (Maximum Segment Size)。MSS告诉对方TCP:“我的缓存所能接收的报文段的数据字段的最大长度是MSS个字节。”(因为通常字节数都很大,所以用MSS来计字节数,更方便一些)

    • 填充:这是为了使整个首部长度是4字节的整数倍。

    TCP连接管理

    TCP是面向连接的协议,因此每个TCP连接都有三个阶段:连接建立、数据传送和连接释放。

    • 连接建立条件:
      • 要使每一方都能够确知对方的存在。
      • 要允许双方协商一些参数(如最大报文段长度MMS、最大窗口值、时间戳选项及服务质量等)
      • 能够对运输实体资源(如缓存大小,连接表中的项目等)进行分配。
    • TCP连接的端口称为套接字(socket)或插口。端口拼接到IP地址即构成套接字。
    • 每条TCP连接唯一地被通信两端的两个端点(即 两个套接字)确定。
    • 采用C/S方式(客户/服务器方式)(客户机是主动发起连接的应用进程,服务器是被动等待连接的应用进程)

    TCP连接建立(三次握手)

    • 第一步:客户机的TCP首先向服务器的TCP发送一个连接请求报文段。其首部中的SYN标志位被置为1(“要同步连接了”),客户机会随机选择一个起始序号字段seq=x(“我的起始序号为x”)(作为最开始的起始序号,要被消耗)。(连接请求报文不携带数据,但要消耗一个序号

      注意:因为客户机还没协商确定发送的起始序号,连接请求报文不携带数据,但要消耗一个序号。

    • 第二步:服务器的TCP收到连接请求报文段后,若同意连接,就发送一个确认报文段,并为该TCP连接分配TCP缓存和变量。SYN=1(“要同步连接了”),ACK=1(“确认收到了连接”),确认号字段ack=x+1(“我收到你发过来的序号x的报文段了,我现在想要你的x+1”),并且服务器随机产生起始序号字段seq=y(“我的起始序号为y”)。(确认报文不携带数据,但也要消耗一个序号

      注意:因为服务器还没协商确定发送的起始序号,确认报文不携带数据,但也要消耗一个序号。

    • 第三步:但客户机收到确认报文段后,还要向服务器给出确认收到,并且也要给该连接分配缓存和变量。ACK=1(“确认收到了”),seq=x+1(“给你发序号x+1的报文段”),ack=y+1(“我想要你的y+1”)。(该报文段可以携带数据,若不携带数据则不消耗序号

      注意:因为此时双方已经协商好了发送的起始序号,所以可以携带数据了。
      该报文段可以携带数据,若不携带数据则不消耗序号。

    注意:服务器端的资源是在完成第二次握手时分配的,而客户端的资源是在完成第三次握手时分配的,这就使得服务器易于受到SYN泛洪攻击。

    • 连接建立:(三次握手)
      1. SYN=1, seq=x
      2. SYN=1, ACK=1, seq=y, ack=x+1
      3. ACK=1, seq=x+1, ack=y+1

        注意:SYN泛洪攻击就是因为发送方发送SYN报文后(第一次握手),接收方发送确认报文并等待,结果发送方不发了。导致资源的浪费。

    TCP连接释放(四次挥手)

    参与TCP连接的两个进程中的任何一个都能终止该连接。

    • 第一步:客户机打算关闭连接时,向其TCP发送一个连接释放报文段,并停止发送数据,主动关闭TCP连接。FIN=1(“我发完了,要释放了”),seq=u(它等于前面已传送过的数据的最后一个字节的序号+1)(“我现在给你发下一个报文段:u,虽然没啥可发的了,意思一下”)。(FIN报文段即使不携带数据,也要消耗一个序号

      注意:因为客户机不想发数据了,所以FIN报文段不携带数据,也要消耗一个序号(这个序号没有要传送的字节)来表示不发了。
      但TCP是全双工的,客户机不发送数据了,但服务器还可以发送数据。

    • 第二步:服务器收到连接释放报文段后即发出确认。ACK=1(“确认收到了”),seq=v(序号等于前面已传送过的数据的最后一个字节的序号+1)(“你发完了,我还没发完呢,我给你发下一个报文段:v”),ack=u+1(“我收到你发过来的u了,我现在期望收到u+1”)

      注意:服务器还是想发送数据的,所以确认报文段可以携带数据。
      此时,从客户机到服务器这个方向的连接就释放了(即 A→B断开),TCP连接处于半关闭状态
      当服务器若发送数据,客户机仍要接收,即 从服务器到客户机这个方向的连接并未关闭(即 B→A连接)
      注意:服务器发送数据,客户端接收时,发送确认接收,seq=u+1(“你怎么还想要啊,我没有数据了,给你个u+1意思一下,最后一次了啊”)(因为服务器期望得到下一个报文段:u+1)(这个u+1就不变了,一直是u+1,因为客户端没有数据要发了),ack=v+n(n按序增加)

    • 第三步:若服务器已经没有要向客户机发送的数据,就通知TCP释放连接,发送连接释放报文段。FIN=1(“我也发完了,释放吧”),ACK=1(“确认知道你要释放了,巧了,我也想释放”),seq=w(“我现在给你发下一个报文段:w,虽然我也没啥可发的了,但是意思一下也不坏”),ack=u+1(“你这u+1给我发的什么啊,怎么什么都没有,再给我发一次”)

      注意:两者都没有报文段要发了,所以不携带数据了。

    • 第四步:客户机收到连接释放报文段后,必须发出确认报文段。ACK=1(“确认收到了”),seq=u+1(“给你给你,你要的u+1”),ack=w+1(“我现在想要下一个w+1”)。(但是这个已经得不到回应了,服务器已经发完了)(所以客户机等了一会要不到,就关闭了

      注意:此时TCP连接还未释放,必须经过时间等待计时器设置的时间2MSL后,A才进入连接关闭状态。

    • 释放连接:(四次挥手)
      1. FIN=1, seq=u
      2. ACK=1, seq=v, ack=u+1
      3. FIN=1, ACK=1, seq=w, ack=u+1
      4. ACK=1, seq=u+1, ack=w+1

        注意:ACK、SYN、FIN一定等于1。
        SYN、FIN不携带数据,只表示控制报文段

    不用二次握手的原因

    考虑这种情况:主机A发出的请求报文段在某些网络节点滞留时间太长,主机A由于超时重发连接请求,收到B的确认建立连接。数据传输完毕释放连接。这时第一个请求才到达B,主机B收到该失效的请求后,误以为A又发出请求,于是向主机A发出确认,同意建立连接。主机A则不会理睬该确认。主机B则苦等A的数据。三次握手就可以防止这种情况的发生。(主机A不会对主机B的确认发出确认,连接就建立不起来)

    其实为什么不用二次握手,总结下来就是一对小情侣的故事。

    • 客户端:我们约会吧!(第一条消息因为网络延迟,一直在转,没发出去)
    • 客户端:我们约会吧!(看发不出去,又发了第二条,第二条秒发出去了)
    • 服务器:好呀好呀!
    • 两个人高高兴兴地去约会了
    • 约会完之后。。结果第一条发出去了
    • 服务器:好呀好呀!
    • 后果可想而知,客户端咕了服务器,服务器一个人在寒风中瑟瑟发抖。

    不用三次挥手的原因

    为何不采用“三次挥手”释放连接,且发送最后一次握手报文后要等待2MSL的时间呢?

    • 保证A发送的最后一个确认报文段能够到达B。如果A不等待2MSL,若A返回的最后确认报文段丢失,则B不能进入正常关闭状态,而A此时已经关闭,也不可能再重传。
    • 防止出现“已失效的连接请求报文段”。A在发送最后一个确认报文段后,再经过2MSL可保证本连接次序的时间内所产生的所有报文段从网络中小事。造成错误的情形与不采用“两次握手”建立连接所描述的情形相同。

      注意:服务器结束TCP连接的时间要比客户端早一些,因为客户机最后要等待2MSL后才可进入CLOSED状态。

    TCP可靠传输

    TCP的任务是在IP层不可靠的、尽力而为服务的基础上建立一种可靠数据传输服务,保证接收方进程从缓存区读出的字节流与发送方发出的字节流完全一致。
    TCP使用了校验、序号、确认和重传等机制来达到这一目的。

    • TCP连接的每一端都必须设有两个窗口——一个发送窗口和一个接收窗口。
    • TCP的可靠传输机制用字节的序号进行控制(链路层滑动窗口是帧的序号)。TCP所有的确认都是基于序号而不是基于报文段。
    • TCP两端的四个窗口处于动态变化之中。(链路层滑动窗口固定
    • TCP连接的往返时间RTT也不是固定不变的(由于网络流量的变化,这个时间会相应地发生改变),需要使用特定的算法估算较为合理的重传时间。

    • 序号:TCP首部的序号字段用来保证数据能有序提交给应用层,TCP把数据视为一个无结构但有序的字节流,序号建立在传送的字节流之上,而不建立在报文段之上。
    • 确认:TCP首部的确认号是期望收到对方的下一个报文段的数据的第一个字节的序号。(默认使用累计确认)
    • 重传:
      • 超时:TCP每发送一个报文段,就对这个报文段设置一次计时器。计时器设置的重传时间到期但还未收到确认时,就要重传这一报文段。

        由于TCP的下层是一个互联网环境,IP数据报所选择的路由变化很大,因而传输层的往返时延的方差也很大。为了计算超时计时器的重传时间,TCP采用一种自适应算法,它记录一个报文段发出的时间,以及收到相应确认的时间,之差为RTT。

        • 加权平均往返时间(RTT_S)(其中权值0≤α<1
          [新RTT_S=(1-α)*(旧RTT_S)+α*(新RTT样本)]

          若选择α→0,表示新RTT标准值与旧RTT标准值相比变化不大,且受新RTT样本的影响不大(RTT值更新较慢)。
          若选择α→1,则表示新RTT标准值受新RTT样本的影响较大(RTT值更新较快)。
          RFC2988推荐的α值是0.25。

        • 显然,超时计时器设置的超时重传时间(Retransmission Time-Out, RTO)应略大于上面得出的加权平均往返时间(RTT_S),计算公式如下:
          [RTO=RTT_S+4*RTT_D]

          其中(RTT_D)是RTT的偏差的加权平均值。它与(RTT_S)和新RTT样本之差有关。

        • 第一次测量时,(RTT_D)取为测量到的RTT样本值的一般,在以后的测量中,使用下式计算:
          [新RTT_D=(1-β)*(旧RTT_D)+β*|RTT_S-新RTT样本|]

          式中,β是个小于1的稀疏,它的推荐值是0.25。

      • 冗余ACK(冗余确认):(即 相同的ACK多了很多)

        超时触发重传存在的一个问题是超时周期往往太长。所幸的是,发送方通常可在超时事件发生之前通过注意所谓的冗余ACK来较好地检测丢包情况。

        • 冗余ACK就是再次确认某个报文段的ACK,而发送方先前已经收到过该报文段的确认。
        • TCP规定每当比期望序号大的失序报文段到达时,就发送一个冗余ACK指明下一个期待字节的序号
        • 三个比期望序号大的失序报文段都到达了(发送了三个冗余ACK),正确期望的那个报文段却还没到达,就认为这个报文段丢失了。
        • TCP规定当发送方收到对同一个报文段的3个冗余ACK时,就可以认为这个报文段已经丢失

          例如,发送方A发送了序号为1、2、3、4、5的TCP报文段,其中2号报文段在链路中丢失,当3、4、5到达B时,B会一连发送3个期望得到2号的冗余ACK。这意味着在2号之后的三个报文段都到了,2号还没到,就可以认为它丢失了。发送方A立即对2号报文进行重传,而不是等到超时没有收到确认之后,重传。

    TCP滑动窗口机制

    • TCP采用大小可变的滑动窗口进行流量控制。窗口大小的单位是字节。(而数据链路层窗口大小的单位是
    • 发送窗口(双方商定):在建立时由双方商定

    • 接收窗口rwnd(receiver window)(接收端确定)(免得收不了):在通信过程中,接收端根据自己的接收缓存的大小,通过接收端向对方发送的TCP报文段首部的“窗口”字段,即 接收端窗口rwnd(receiver window),向发送方通报接收端缓冲区的接收能力,从而动态地随时调整控制发送端的发送窗口的上限值。

    • 拥塞窗口cwnd(congestion window)(发送端确定)(免得发出去堵车)发送端根据其对当前网络拥塞程度的估计而确定的窗口值。其大小与网络的带宽和时延密切相关。

      注意:只有发送窗口接收窗口滑动窗口拥塞窗口只是一个由当前网络状况决定的数值(用来决定发送窗口),而不是滑动的窗口。

    • 发送端设置的当前能够发送数据量的大小叫做发送窗口,发送窗口的上限值需要根据上面两个因素共同决定:
      [发送窗口的上限值=Min(拥塞窗口cwnd,接收窗口rwnd)]
    • rwnd由接收端根据其接收缓存确定,发送端确定cwnd比较复杂,其涉及TCP的网络拥塞控制。

    • 窗口的移动:

      窗口两个边沿的相对运动增加或减少了窗口的大小。

      • 窗口合拢:当窗口左边沿右边沿靠近时。
      • 窗口张开:当窗口右边沿右移动时。
      • 窗口收缩:右边沿左移动时。(接收方向发送方发出的TCP报文的窗口字段变小时)
    • 注意:
      • A的发送窗口并不总是和B的接收窗口一样大(因为有一定的时间滞后)
      • TCP标准没有规定对不按序到达的数据应如何处理。通常是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后再按序交付上层的应用进程。
      • TCP要求接收方必须有累积确认的功能(一次确认一个报文段,而不是对每个字节都要发回确认),这样可以减小传输开销。

        注意:TCP是面向字节的。对每个字节进行编号,但并不是收到每个字节都要发回确认,而是在发送一个报文段的字节后,才发回一个确认,所以TCP采用的是对报文段的确认机制

    TCP流量控制

    采用可滑动窗口机制,装在发送端(发送窗口)接收端(接收窗口)
    一般说来,我们总是希望数据传输得更快一些。但如果发送方把数据发送得过快,接收方就可能来不及接收,这就会造成数据的丢失。流量控制(flow control)就让让发送方的发送速度不要太快,既要让接收方来得及接收,又不要使网络发送拥塞。

    • 利用滑动窗口机制可以很方便地在TCP连接上实现流量控制。
    • 滑动窗口大小的单位是字节

    TCP拥塞控制

    拥塞控制:是指防止过多的数据注入网络,以使网络中的路由器或链路不至于过载。

    • 与流量控制的区别:
      • 流量控制:往往指点对点通信量的控制,是个端到端的问题(接收端控制发送端)(如 在马路上行车,交警跟红绿灯是流量控制。
      • 流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收。
      • 拥塞控制:是让网络能够承受现有的网络负荷,是一个全局性的过程。(如 当发生堵车时,如何进行疏散,是拥塞控制


      • 流量控制中,发送方发送数据的量由接收方决定
      • 拥塞控制中,发送方发送数据的量由发送方自己通过检测网络状况来决定
      • 流量控制是不要搞太快数据,没有流量控制会消化不良
      • 拥塞控制是不要搞太多数据,没有拥塞控制会噎着

    • TCP采用基于窗口的方法进行拥塞控制。该方法属于闭环控制方法。
    • TCP发送方维持一个拥塞窗口CWND(Congetsion Window)
      • 拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化
      • 发送端利用拥塞窗口根据网络的拥塞情况调整发送的数据量。
      • 所以,发送窗口的大小不仅取决于接收方公告的接收窗口,还取决于网络的拥塞情况,所以真正的发送窗口值为:
        [真正的发送窗口值=Min(公告接收窗口值,拥塞窗口值)]
    • 控制拥塞窗口的原则:
      • 只要网络没有出现拥塞拥塞窗口就可以再大一些,以便把更多的分组发送出去,这样就可以提高网络的利用率。
      • 只要网络出现拥塞有可能出现拥塞,就必须把拥塞窗口减小一些,以减少注入到网络中的分组数,以便缓解网络中出现的拥塞。
    • 拥塞的判断:
      • 重传定时器超时:

        现在通信线路的传输质量一般都很好,因传输出差错而丢弃分组的概率是很小的(远小于1%)。只要出现了超时,就可以猜想网络可能出现了拥塞。

      • 收到三个相同(重复)的ACK

        个别报文段会在网络中丢失接收方没有收到,连续发了三个相同ACK),预示着可能会出现拥塞(实际未发生拥塞),因此可以尽快采取控制措施,避免拥塞。

    拥塞避免算法

    拥塞窗口是卫星通信在因特网中防止通信拥塞的一种措施,它是一个装在发送端的可滑动窗口。

    • 注意:以下所说的增加或减少,为了方便都是按一个MSS的大小。(但是单位还是字节,而不是MSS)
    • 慢开始(slow-start):(*2)(每收到一个对新的报文段的确认拥塞窗口cwnd+1)
      • 用来确定网络的负载能力。
      • 初始拥塞窗口cwnd设置:cwnd=1,即 一个最大报文段长度MSS
      • 慢开始门限ssthresh(Slow Start THRESHold)(状态变量)(阈值):防止拥塞窗口cwnd增长过大引起网络拥塞。
      • 拥塞窗口cwnd控制方法:在每收到一个对新的报文段的确认后,可以把拥塞窗口cwnd+1,即 增加最多一个MSS的数值。很显然,这是一个指数增长,每经过一个传输轮次,拥塞窗口就加倍。每次*2。

        例如,发送一个,确认一个,cwnd+1=2;发送两个,确认两个,cwnd+2=4;发送四个,确认四个,cwnd+4=8...
        一个传输轮次所经历的时间其实就是往返时间RTT。

    • 算法切换:
      • cwnd<ssthresh时,使用慢开始算法。
      • cwnd>ssthresh时,停止使用慢开始算法而改用拥塞避免算法。
      • cwnd=ssthresh时,即可以使用慢开始算法,也可以使用拥塞避免算法。

        实际应用中,相等时往往使用拥塞避免算法。

    • 拥塞避免(congestion avoidance):(+1)(每经过一个往返时间RTT拥塞窗口cwnd+1)
      • 思路:让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd+1,而不是加倍,使拥塞窗口cwnd按线性规律缓慢增长。
      • 因此在拥塞避免阶段就有“加法增大”(Additive Increase)的特点。这表明在拥塞避免阶段,拥塞窗口cwnd按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多。
    • 网络拥塞的处理:

      当网络出现拥塞时,无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(重传定时器超时

      1. (ssthresh=max(拥塞窗口cwnd/2, 2))门限减半
      2. (cwnd=1)(拥塞窗口从头开始
      3. 执行慢开始算法

        这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。

      注意:这个图代表第n次传输后的拥塞窗口数值。
      传输次数为0时,代表初始拥塞窗口为1,代表第0次传输拥塞窗口为1;
      而第一次传输结束(这个横坐标就代表传输结束后的值),拥塞窗口变为了2(即 代表第一次传输的拥塞窗口是1,而传输第一次传输结束拥塞窗口就变为了2;2作为第二次传输的拥塞窗口进行传输)。(即 经过1个RTT后,拥塞窗口为2)(也可以说是收到第1个确认段后,拥塞窗口变为了2

      传输次数 0 1 2 3
      拥塞窗口 初始为1 第一次传输变为了2 第二次传输变为了4 第三次传输变为了8
      备注 第一次传输传输1 第二次传输传输2 第三次传输传输4 第四次传输传输8
    • 总结:(当发送方检测到超时的时候,就采用慢开始和拥塞避免)(从头开始,门限减半
      • 慢开始(*2)(指数上升)
      • 到达门限,拥塞避免(+1)(线性上升)
      • 出现拥塞(超时)
      • 门限减半
      • 从头开始(拥塞窗口从头1开始)
      • 慢开始算法
      • 。。。

    快重传和快恢复算法是对慢开始和拥塞避免算法的改进。

    • 快重传(fast retransmit):
      • 采用快重传FR (Fast Retransmission)算法可以让发送方尽早知道发生了个别报文段的丢失。

      • 快重传算法首先要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认。
      • 发送方只要一连收到三个重复确认,就知道接收方确实没有收到报文段,因而应当立即进行重传(即“快重传”),而不必等待那个报文段设置的重传计时器超时。这样就不会出现超时,发送方也不就会误认为出现了网络拥塞。
      • 使用快重传可以使整个网络的吞吐量提高约20%。

        不难看出,快重传并非取消重传计时器,而是在某些情况下可更早地重传丢失的报文段。

    • 快恢复(fast recovery):加法增大,乘法减小(AIMD)算法
      • 发送端收到连续三个重复的确认时,由于发送方现在认为网络很可能没有发生拥塞,因此现在不执行慢开始算法,而是执行快恢复算法FR (Fast Recovery) 算法:
      1. (慢开始门限ssthresh=当前拥塞窗口cwnd/2)“乘法减小”(Additive Increase, AI))
      2. (新拥塞窗口cwnd=慢开始门限ssthresh)
      3. 开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大。“加法增大”(Multiplicative Decrease, MD))

        由于跳过了cwnd从1起始的慢开始过程,所以被称为快恢复

    注意:实际上,慢开始、拥塞避免、快重传和快恢复几种算法应是同时应用在拥塞控制机制之中的。
    当发送方检测到超时的时候,就采用慢开始和拥塞避免
    当发送方接收到冗余ACK时,就采用快重传和快恢复


    • 发送窗口的上限值:
      • 发送方的发送窗口的上限值应当取为接收方窗口rwnd拥塞窗口cwnd这两个变量中较小的一个,即应按以下公式确定:
        [发送窗口的上限值=Min[rwnd, cwnd]]
      • rwnd<cwnd时,是接收方的接收能力限制发送窗口的最大值。
      • cwnd<rwnd时,则是网络的拥塞限制发送窗口的最大值。

        也就是说,rwnd和cwnd中数值较小的一个,控制了发送方发送数据的速率。

    • 总结:(当发送方接收到冗余ACK时,就采用快重传和快恢复)(拥塞减半,门限拥塞
      • 冗余ACK快重传和快恢复
      • 门限=拥塞窗口的一半
      • 拥塞窗口=新门限
      • 拥塞避免(+1)


        我的理解:

      • 拥塞窗口减半
      • 门限=拥塞窗口
      • 此时拥塞窗口到达门限了,所以用拥塞避免(+1)

    注意:
    超时的时候cwnd被置为1:(因为超时的时候,一个ACK都没有传过来,网络拥塞很严重,所以发送方得最大限度地一直数据发送量)
    三个冗余ACK的时候cwnd减半:(因为收到三个冗余ACK的时候,代表有三个ACK报文段能被正确交付,网络拥塞没有那么严重,所以减半)

    总结

    • 固定首部:
      • UDP数据报:8B(首部完全固定)
      • TCP报文段:20B(首部可变)
      • IPv4数据报:20B(首部可变)
      • IPv6数据报:40B(首部完全固定)
    • 长度字段:
      • UDP数据报:
        • 长度:是UDP数据报整个的长度(包括首部和数据),单位为1B

          注意:因为UDP数据报首部长度固定的8B(没有可变部分),所以没有必要再设置首部长度字段。

      • TCP报文段:
        • 首部长度(只有首部),单位为4B

          注意:因为最大报文段长度MSS是约定好的,所以不需要整个长度,只用知道首部长度。

      • IP数据报:既有首部长度,又有总长度(包括首部和数据)
        • 首部长度:占4位,单位为4B
        • 总长度:占16位,单位为1B
        • 片偏移:占13位,单位为8B

          记忆方法:你不要是拿1条首饰(首4)来骗()我吧(8

      • IPv6数据报:载荷长度=扩展报头和负载数据=数据报长度-40(固定首部)
        • 载荷长度:占20位,单位为1B

    首部长度都是以4B为单位(首部长度较短,无需精确单位)(IPv6首部长度必须是8B的整数倍),总长度都是以1B为单位(总长度需要精确的单位),片偏移都是以8B为单位(因为数据较长,所以单位大一些,无需精确单位,每个分片的长度一定是8B的整数倍(除最后一个片外))。

    • 检验和:
      • UDP数据报:检查整个UDP数据报(首部和数据部分)(
      • TCP报文段:检查整个TCP报文段(首部和数据)(
      • IP数据报:只检查IP数据报的首部(因封装变了,所以只检验首部)

        注意:IP数据报每经过一个路由器,路由器都要重新计算校验和(一些字段,比如生存时间、片偏移等可能发生变化);不校验数据部分,主要是为了减少软件计算量。

      • IPv6不进行首部检查和,从而更快速处理IP分组。

  • 相关阅读:
    html5储存篇(二)
    html5 存储篇(一)
    【刷题计划1】【poj分类转载】【8月20号开始】
    【如何搭建一个属于自己的独立博客~~~基于windows系统,使用wordpress建站】【弱菜一枚~~大神请路过】
    第六章 6.6 图的应用
    第六章 6.5 图的遍历
    第六章 6.4 图的存储结构
    poj 2488 A Knight's Journey 【dfs】【字典序】【刷题计划】
    【Educational Codeforces Round 33 B】Beautiful Divisors
    【 Educational Codeforces Round 33 A】Chess For Three
  • 原文地址:https://www.cnblogs.com/blknemo/p/11561831.html
Copyright © 2011-2022 走看看