网络运输层小结

运输层

  1. 运输层和网络层的关系

    概述:在协议栈中,运输层恰好位于网络层之上。网络层提供了主机之间的逻辑通讯,而运输层为运行在不一样主机上的进程之间提供了逻辑通讯。缓存

    比如两个家庭的孩子互相写信,而后由某一个大孩子负责将全部的信交到邮局和从邮局收集到全部人的信而后分发给各个孩子。中间的传输则交给邮局来处理。此处,服务器

    应用层报文=信封上的字符

    进程=堂兄弟姐妹网络

    主机(又称为端系统)=家庭tcp

    运输层协议=负责收发的两个大孩子spa

    网络层协议=邮政服务(包括邮车)线程

    *注:而对于不一样的运输层协议,就比如不一样的大孩子,可能这些大孩子比较粗心,会有遗漏,或者有丢失。code

    运输协议可以提供的服务经常受制于底层网络层协议的服务模型。若是网络层协议没法为主机之间发送的运输层报文段提供时延或带宽保证的话,运输层协议也就没法为进程之间发送的应用程序报文提供时延或带宽保证。blog

    服务扩展:将两个端系统间IP的交付服务扩展为运行在端系统上的两个进程之间的交付服务进程

  2. 多路复用与多路分解

    进程,套接字,端口号:一个进程对应一个端口号,可是一个端口号能够对应于多个套接字。ip

    多路复用和多路分解是在套接字层面进行讨论的,多路分解:从网络层传输上来的信息可能来自不一样主机,或同一主机的不一样进程,要把这些报文段发向正确的进程,这就是多路分解,将信息分拣出来。多路复用:同理,在源主机从不一样套接字中收集数据块,并为每一个数据块封装上首部信息(这将在之后用于分解)从而生成报文段,而后将报文段传递到网络层。

    端口号分配:若是应用程序开发者所编写的代码实现的是一个“周知协议”的服务器端,那么开发者就必须为其分配一个相应的周知端口号。一般,应用程序的客户端让运输层自动地(并 且是透明地)分配端口号,而服务器端则分配一个特定的端口号。

    一个UDP套接字是由一个二元组(目的IP地址,目的端口号)识别的,即当两个具备相同的目的IP地址和目的端口号发至这个主机的网络层时,运输层将把它们发往相同的目的套接字和相同的目的进程。 原端口号和原IP地址的做用主要是当以前的接收方须要回发一个报文给以前的发送方式,能够从以前的报文中获取相关信息。

    一个TCP套接字是由一个四元组(源IP地址,源端口号,目的IP地址,目的端口号)识别的。因此即便两个TCP报文段具备相同的目的IP地址,目的端口号,若是他们来自于不一样的IP地址或者不一样的端口号,那么他们就会被定向到不一样的套接字。问题:进程、端口号、套接字的对应关系?以服务器做为主角,当有两个不一样用户访问同一个服务器上的同一个进程时,这时由TCP套接字的标识可知,服务器会新建一个套接字以供服务,这就是线程

  3. 无链接运输:UDP

    运输层最低限度必须提供一种复用/分解服务,以便在网络层与正确的应用级进程之间传递数据。 而UDP只是作了运输协议可以作的最少工做:复用/分解功能及少许的差错检测外。

    无链接:使用UDP时,在发送报文段以前,发送方和接收方的运输层实体之间没有握手。如使用了UDP协议的DNS。

    主机端的UDP为查询报文添加首部字段,而后将造成的报文段交给网络层。网络层将此UDP报文段封装进一个IP数据报中,而后将其发送给一个名字服务器。在查询主机中的DNS应用程序则 等待对该查询的响应。若是它没有收到响应(多是因为底层网络丢失了查询或响应),则要么试图向 另外一个名字服务器发送该査询,要么 通知调用的应用程序它不能得到响应。

    ### UDP报文段结构:todo

    ### UDP检验和

    发送方的UDP对报文段中的全部16比特字的和,在计算和的时候,对溢出的进位进行回卷(也就是把溢出的数字再加到数字的尾部,反复循环直至没有溢出),计算完和以后再对这个和取反获得的结构就是检验和。在接收方UDP将传输过来的全部16比特字再进行求和并将检验和也一并求和,最后得出的结果若为16个1则代表没有出错,如有0则代表出错了。

    端到端原则的体现:在既没法确保逐链路的可靠性,又没法确保内存中的差错检测的状况下,若是端到端数据传输服务要提供差错检测,UDP就必须在端到端基础上在运输层提供差错检测。与在较高级别提供这些 功能的代价相比,在较低级别上设置的功能多是冗余的或几乎没有价值的。可是UDP的对差错的恢复无能为力,它只能作到丢弃受损的报文段,或者将受损的报文段交给应用程序并给出警告。

  4. 可靠数据传输原理

    rdt1.0:假设信道是彻底可靠的,即在传输过程当中不存在出错,那么发送方发完以后就万事大吉了,直接等到上一层的新数据。

    对于如何判断数据包是否产生错误,采用的是以前讲过的校验码checksum

    rdt2.0:由于信道不多是彻底可靠的,因此在传输的过程当中,经过NAK和ACK做为反馈信号,当接收了而且是未损坏的数据时,则向发送发返回一个ACK,过程结束。若接受了可是是损坏的数据时,则向发送方返回一个NAK,接收方等待,发送方进行重传操做。问题:停等,NAK/ACK出错的话会产生混乱。

    利用状态进行判断,之前的话只是经过验证码NAK/ACK进行判断,如今增强,不只仅看验证码还要看当前所处的状态与传过来的验证码是否匹配。

    rdt2.1:主要解决的是2.0中出现的反馈信息出错的问题,添加了01编号,也就是说01分别表明两个数据包,而后这样循环往复。①那么发送的人发送0号数据包,发送的的人开始等待反馈信息,此时接受者若接收到0号数据包未损坏,则返回ACK,可是ACK在途中发生错误跳转成了NAK或损失成乱七八糟的东西,此时发送方进行重传0号数据包,到了接收方,可是由于接收方以前正确接受了0号数据包处于等待1号数据包的状态,因此会出现拒收,避免冗余。②发送的人发送0号数据包,可是由于有损伤因此接收方发送NAK,可是若NAK变成了ACK,此时发送方就继续发送1号数据包了,因为接受者还处于接收0号数据包的状态,因此会拒绝1号数据包,避免错序。

    rdt2.1中

    ss发送0号数据包,rr收到以后发现损坏返回NAK并进入等待0号数据包,可是NAK在途中跳转成了ACK,ss收到ACK以后发送1号数据块,rr接收到1号数据块以后返回ACK,ss接收到ACK就继续循环了,那么0号数据包不就一直没传过去嘛?也就是说,我感受ss没法判断rr传过来的是对0号数据的ACK仍是对1号数据的ACK啊解答:用checksum对反馈数据进行检验,因此即便是NAK转变成了ACK,ss仍是会判断他是错的,因此仍是会进行重发。

    rdt2.2:其实仔细分析以上的状态转换会发现,接受者发送NAK/ACK代表的意思不就是我还想要当前数据包再给我重发一份和我已经接收了当前数据包你能够发下一份了。那么在2.2中,ss会在发送的数据包进行01编号,对于rr而言,只要你的数据包有损坏或者你发的不是rr当前所处状态的数据包(好比说rr处在接收0号数据包的状态结果传来了1号数据包或者0号有损数据包,那么我就返回ACK,1就行了,这个1既能够表明有损,也能够表明传错),由于这样的一个返回对ss来讲都是进行一样的操做也就是重传。也至关于将2.1rr端的几种状况进行合并,由于这对ss而言所作的操做是同样的。问题:既然每次返回都是ACK,ACK还有什么存在的意义呢?

    rdt3.0:这就比较好理解了,在2.2的基础上(可以处理冗余数据包)若数据包卡在了传输路上或者反馈信号卡住了,那么一直等下去毕竟不是个办法,因此增长了一个定时功能,若反馈信号在时间内都没有到达的话就直接重传。

    ### 流水线(pipelining)操做:

    解决了2.0中就出现的停等问题,停等的话ss必须得等到返回当前数据包的一个正向反馈为止。也就是在一个RTT的时间内都须要在等待,而流水线则是在这个RTT中反复发送多个分组,而后以后再等反馈信息。

    • 回退N步-GBN

      N的含义:由于在RTT中能够反复发送多个分组,可是我须要发完分组后收到分组的正反馈而后继续发送。那么GBN就是在流水线中未确认的分组数不能超过某个最大容许数N。
    • 选择重传-SR

gbn-sr-tcp.png

  1. 流量控制

    一条TCP链接的时候都会为接收方和发送方配备一个接收缓存,当对方发送的数据过快时,可将收到的数据先暂时放在缓存中,而后上层一点一点读取。这里不与以前说的乱序包裹产生冲突,乱序包裹应该也是放在这个缓存中,等待失序的包裹到来时,一块儿交付给上层。流量控制就是为了控制这个缓存空间不会被溢出,由于溢出了接下来的包裹就会被丢弃。

    假设主机A向主机B发送一个大文件。主机B会对本身的接收缓存设置两个变量:

    批注 2020-03-31 132753.png

    并用RcvBuffer表示缓存空间的大小。显然可知:

    LastByteRcvd - LastByteRead<=RcvBuffer

    由此可计算出B的缓存可用可见,用接收窗口rwnd表示:

    rwnd = RcvBuffer - [ LastByteRcvd - LastByteRead ],

    主机B会将rwnd的值放入它发给主机A的报文段接收窗口字段中,也就是告知主机A我还有多少的空间供你使用。

    同理,主机A的缓存空间也有两个变量:LastByteSent和LastByteAcked,也就是最后发送和最后被正确接收的,易得LastByteSent-LastByteAcked也就是发送还为接收的数据,控制LastByteSent-LastByteAcked这个数据的大小要小于rwnd便可。

    但实际上还有一个小bug,就是rwnd是须要依附在B向A发送的报文段上的,若B的缓存空间已满,在告知A本身rwnd已经为0以后,再也不向A发送任何反馈信息。这时的A就至关于被阻塞了而不能再发送数据。(B将数据收到缓存中就会向A发送ACK了

    解决:TCP规范中要求:当主机B的接收窗口为0时,主机A继续发送只有一个字节数据的报文段。这些报文段将会被接收方确认。最终缓存将开始清空,而且确认报文里将包含一个非0的 rwnd 值。

  2. 拥塞带来的问题

    拥塞形成的问题.png

  3. 拥塞控制

拥塞控制办法-tcp.png

相关文章
相关标签/搜索