注意:只有主机的协议栈才有运输层,而网络核心部分的路由器在转发分组时都只用下三层(物理层、数据链路层、网络层)的功能。
我们知道,IP协议能够把源主机A发送的分组按照首部中的目的地址发送给目的主机B,那么为什么还需要传输层呢?
从IP层来看,通信的两端是两个主机,但是通信的实质并不是主机之间的通信,而是主机的进程间的通信,,端到端的通信指的就是应用进程间的通信,而传输层真正意义上实现了端到端通信。
(1)用户数据报协议UDP
(2)传输控制协议TCP
UDP在传输数据之前不需要建立连接,远方主机的传输层在收到UDP报文后,也不需要给出确认,即UDP提供了不可靠传输,如:DNS域名解析器、QQ聊天和屏幕分享广播。
而TCP则是面向连接的传输服务,数据传送之前应该建立连接而数据传输之后释放连接。由于TCP提供的是可靠的、面向连接的服务,不可避免地增加一些开销。
UDP和TCP的对比见上一篇博客 计算机网络问题集锦
下面介绍在传输层中会用到的几个
复用:发送方的不同应用进程都可以使用同一个运输层。
分用:接收方的传输层接收到
IP报文以后,将报文去掉头部后可分发给不同而应用进程。
UDP知识在IP服务至善加了一点功能:分用、复用、差错检测。
UDP特点如下:
(1)无连接 因此减小了开销和时延。
(2)尽最大努力交付,即提供的是不可靠传输。
(3)面向报文的传输
(4)没有拥塞控制
(5)支持一对一、一对多、多对多和多对一的通信
(6)首部开销比较小
TCP的主要特点如下:
(1)TCP是面向连接的协议
(2)每一条TCP连接只能有两个端点, 每一条TCP连接都必须是点对点的。
(3)提供可靠传输
(4)面向字节流的传输
(5)全双工通信
TCP把连接作为基本的抽象。TCP的很多特征都与TCP是面向连接的这一基本特征有关。TCP连接的端点叫做套接字或插口。
套接字socket=(IP地址:端口号)
每一条TCP连接唯一地被通信两端的连个端点所确定,即:
TCP连接::={sockte1,socket2}={(IP1:port1),(IP2:port2)}
为了实现可靠传输,我们可以采用停止等待协议(简单地说,停止对等待协议要求A发送数据后等待B的确认消息,A收到B的确认后再发送下一条分组,当确认丢失或者确认迟到后就要进行重传),但是停止等待协议的效率太低。
为了提高停止等待协议的传输效率,采用了流水线传输的方式(流水线传输就是发送方可以连续发送多个分组,不需要每个分组都要等待确认)
此处省略了TCP报文段首部1格式的介绍,这部分内容虽然简单,但需要理解清楚,并记忆几个重要的部分,只有弄清楚TCP首部各个字段的作用才能掌握TCP的工作原理。
关于滑动窗口问题的几点强调:
第一,虽然A的发送窗口是根据B的接受窗口所设定的,但是在同一时刻,A的发送窗口并不是总和B的接收窗口一样大,这是因为通过网络传送窗口值也存在一定的时滞后,(A可以根据网络的拥塞情况,来适当地减少自己的的窗口大小)
第二,对于不按顺序到达的数据该如何处理,TCP并无明确规定。如果接收方把没有按照顺序到达的数据一律丢掉,则接收窗口的管理会比较简单,但是对网络资源的利用不利(因为发送方要重新发送数据)。
第三,TCP要求接收方应该有累积确认的功能,这样可以减少传输的开销。接收方可以在适当的时候发送确认,也可以在自己有数据要发送的时候把确认信息捎带上。但是接收方不应该过分推迟发送确定,因为会造成发送方的不必要重传。
利用滑动窗口实现流量控制。
一般来说,我们总是希望数据传输得更快一些。但如果数据发送的过快,接收方就可能来不及接收,这就造成了数据的丢失。所谓的流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。
利用滑动窗口技术,就可以很好的实现对发送方的流量控制。
这个流量控制过程简单地说就是:设A向B发送数据。B会告诉A他的接收窗口是多大,A的发送窗口就不会大于B的接收窗口。比如当B告诉A他的接收窗口是300时,A的发送窗口就不会大于300.当B的接收窗口为0时,A就会暂停数据的发送。注意: 此时,当B的接收缓存又有了一些存储空间后,比如这个缓存空间是100,那么B就会向A发送一个窗口是100的非零窗口报文段。但是这个报文段在传送的过程中很有可能会丢失,但A一直在等待B的非零窗口的通知,这就会陷入死锁,即一直等待状态。为了解决这个问题,TCP为每一个连接设置了一个持续计时器,只要TCP连接中的一方收到了对方发送的零窗口通知,这个计时器就会启动。若计时器到期,则就会发送一个零窗口探测报文段,以打破死锁。
······带宽、结点的缓存容量、处理机都是网络的资源。若某个时间段,对资源的需求量大于了该资源所能提供的可用部分,网络性能就会变坏。这个现象就是拥塞。
造成网络拥塞的原因有很多:
比如结点的缓存不足,到达该结点的分组因为无法储存,而不得不丢掉,当扩充缓存后,因为处理机速度不足,同样会出现分组队满后丢包的现象。解决了处理机的速度问题以后,其他的问题又会随之而来。问题的实质往往是整个系统的各个部分不匹配,只有所有的部分都平衡了,问题才会得到解决。
拥塞控制:就是防止过多的数据注入到网络中,这样可以使网络中的路由器或者链路不过载,拥塞控制是一个全局性的过程,涉及到所有的主机、所有的路由器,以及降低网络传输性能的相关的所有因素。流量控制往往是点对点的通信量的控制,是一个端到端的问题。
·····拥塞控制的算法主要有四种,在讨论这四种算法时为我们假定:
(1)数据是单向的
(2)假定接收方和发送方都有足够大的缓存空间,因而发送窗口的大小由网络的拥塞程度来决定。(感觉这个也是拥塞控制和流量控制的一个大的区别)。
拥塞控制可以分为开环控制和闭环控制:
开环控制,在设计网络时把因素考虑到
闭环控制,基于反馈环路,使用拥塞的信息来进行调整网络。
1慢开始和拥塞避免
发送方维持一个叫做拥塞窗口cwnd,根据网络来进行动态的调整大小,网络拥塞的时候,路由器会丢弃报文,当发送方没有按时收到确认报文,那么就知道网络发生了拥堵。现在结合拥塞窗口cwnd的变化来看一下上述两个方法。慢开始的“慢”指的是,初始cwnd=1(此时表示的是报文段的个数,而不是真正传输时使用的字节流)。
我们来简单的论一下这个过程:
(1)开始时发送方cwnd=1,发送报文段M1,如果收到确认M1,那么此时增大cwnd=2,并发送M2,M3
(2)要注意,发送方每收到一个确认报文段,cwnd+1(不包括缺失重传的确认)也就是说,每经过一个传输伦次(RTT时间),cwnd加倍。但是,为了防止拥塞窗口cwnd增长过大而引起网络拥塞,设置一个慢开始门限ssthresh。
~~当cwnd
~~当cwnd==ssthresh,两者都可以使用
接下来介绍一下拥塞避免算法:
拥塞避免算法的思路是让拥塞窗口cwnd缓慢增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd+1,而不是加倍(也就是收到两个,四个确认,仍然+1),这样cwnd就按线性增大。
无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞,就把慢开始门限ssthresh设置为出现拥塞时的发送窗口大小的一半。然后把拥塞窗口cwnd设置为1,执行慢开始算法。如下图:
这部分内容比较重要,见另外一篇文章 TCP连接之三次握手四次挥手