一、运输层概述
运输层(传输层),解决的是计算机程序到计算机程序之间的通信问题,即所谓的“端”到“端”的通信(网络层解决的是主机到主机之间的通信)。引入传输层的原因: 增加复用和分用的功能、 消除网络层的不可靠性、 提供从源端主机到目的端主机的可靠的、与实际使用的网络无关的信息传输。运输层的最终目标是为传送服务用户提供有效、可靠和价格合理的运输服务,而传送服务的用户即会话层实体。
运输层一个重要功能——复用和分用。复用是指在发送方不同的应用进程都可以使用同一个运输层协议传送数据,分用是指接收方的运输层在剥去报文首部后能够把这些数据正确交付目的应用进程。
运输层还要对收到的报文进行差错检测。在网络层,IP数据包首部中的检验和字段只检验首部是否出现差错而不检验数据部分。
运输层向高层屏蔽了下面网络核心的细节,他使应用进程看见的就是好像两个运输层之间有一条端对端的逻辑通道。
运输层的寻址和端口:
应用程序 | FTP | TELNET | SMTP | DNS | TELNET | HTTP | SNMP |
端口号 | 21 | 23 | 25 | 53 | 69 | 80 | 161 |
(熟知端口号<0-1023>:给TCP/IP最重要的一些应用程序,让所有用户知道)
二、用户数据报协议UDP&&传输控制协议TCP
用户数据报协议UDP:UDP只是在IP数据包服务上增加了很少的功能,即复用分用和差错检测功能。
①UDP是无连接的,减小开销和发送数据之前的时延,传输数据前不用建立连接,收到UDP报文后不用给出确认;
②UDP使用最大努力交付,既不保证可靠交付;
③UDP是面向报文的,一次交付一个完整的报文;
④UDP无拥塞控制,时延小,适合实时通信;
⑤UDP首部开销小,只有8B,而TCP首部20B;
⑥UDP支持一对一、一对多、多对多的交互通信;
传输控制协议TCP:
①TCP是面向连接的,传输数据前必须建立连接,数据传输完成后释放连接;
②TCP不提供广播和多播服务,只能一对一传输;
③TCP提供可靠交付的服务;
④TCP提供全双工通信;
⑤面向字节流,TCP把应用程序交下来的数据看成一连串的无结构的字节流(流入到进程或从进程流出的字节序列);
三、UDP数据报&&UDP检验
1.UDP数据报格式
用户数据报UDP有两个字段:首部字段和数据字段。首部字段占有8个字节,有四个字段(源端口、目的端口、长度、检验和)组成,每个字段长度都是两个字节。当运输层从IP层收到UDP数据报时,根据首部中的目的端口,把UDP数据报通过相应的端口,上交最后的终点--应用进程。
伪首部(12B):并不是真正的首部,只在UDP检验时出现,与IP首部相同,不向下传递也不想上提供;
源端口:源端口号,在需要对方回信时选用。不需要时可全为0;
目的端口:目的端口号,这在终点交付报文时必须使用到;
长度:UDP用户数据报的长度,其最小值是8B(首部长度);
检验和:检测UDP用户数据报在传输中是否有错,有错就丢弃;
2.UDP检验和
在发送端:①添加伪首部(源IP地址+目的IP地址+全0+17+15)
②全0添加校验和字段
③全0填充数据字段(用0补全)
④伪首部+首部+数据部分采用二进制反码求和
⑤将上述的和求反码填入检验和字段
⑥去掉伪首部,发送
在接收端:①填上伪首部
②伪首部+首部+数据部分 采用二进制反码求和
③结果全为1则说明无差错。反之丢弃或者交给应用层并附上出错警告
四、传输控制协议TCP
1.TCP连接
每一条TCP连接唯一的被通信的两个端点(即两个套接字)所确定。套接字socket=(IP地址:端口号),例如192.168.1.1:80。
2.TCP可靠传输
2.1工作原理
TCP报文是交给IP层传送的,但是IP曾只能提供尽最大努力服务(不可靠传输)。因此TCP必须采取适当的措施才能使得传输可靠。停止等待ARQ协议和连续ARQ协议都属于自动重传请求协议ARQ(数据链路层的错误纠正协议之一)的一部分。
2.1.1 停止等待ARQ协议:停止等待就是每发送完一个分组就停止发送,等待对方的确认。在收到确认之后再发送下一个分组。在传输过程中会出现无差错情况(正常)、出现差错(重传)、确认丢失(接收方返回的确认消息丢失,发送方到固定时间重传,接收方会丢弃第二次的数据并且返回新的确认)和确认迟到(发送方返回的确认信息丢失,则接收方接收到延时的确认信息时直接丢弃,接收方收到重复的数据时也直接丢弃)四种情况。停止等待协议简单但是信道利用率低。
2.1.2 连续ARQ协议
可提高信道利用率,发送方维持一个发送窗口。凡是位于发送窗口的分组可以连续的发送出去,而不需要等待对方的确认。接收方一般采用累计确认,对按序列到达的最后一个分组发送确认,表明到这个分组为止的所有分组都已经正确收到了。
2.2 TCP可靠传输的实现
1. 数据包校验:目的是检测数据在传输过程中的任何变化,若校验出包有错,则丢弃报文段并且不给出响应,这时 TCP 发送数据端超时后会重发数据;
2. 对失序数据包重排序:既然 TCP 报文段作为 IP 数据报来传输,而 IP 数据报的到达可能会失序,因此 TCP 报文段的到达也可能会失序。TCP 将对失序数据进行重新排序,然后才交给应用层;
3. 丢弃重复数据:对于重复数据,能够丢弃重复数据;
4. 应答机制:当 TCP 收到发自 TCP 连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒;
5. 超时重发:当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段;
6. 流量控制:TCP 连接的每一方都有固定大小的缓冲空间。TCP 的接收端只允许另一端发送接收端缓冲区所能接纳的数据,这可以防止较快主机致使较慢主机的缓冲区溢出,这就是流量控制。TCP 使用的流量控制协议是可变大小的滑动窗口协议。
3.TCP报文结构
源端口和目的端口(2B、2B):分别写入源端口号和目的端口号。
序号(4B):指本报文段所发送的第一个字节的序号。
确认号(4B):期望收到对方下一个报文段的第一个数据的序号。若确认号为N,这表明到序号N-1位置的所有数据都以正确收到。
数据偏移(4B):首部长度——TCP报文段的数据起始处到TCP报文段起始处的距离。
保留(6位):留着以后用,置为0.
紧急URG:URG=1时表明此报文段中有紧急的数据,是高优先级的数据,不在缓存中排队,配合紧急指针使用。
确认位ACK:ACK=1时表明此报文段有效,建立连接后所有的报文段都必须将ACK置为1.
推送位PSH:PSH=1时接收方应该尽快交付应用进程,不用等待缓存填满再向上交付。
复位PST:PST=1时表明TCP连接出现严重出错,需要释放连接重新建立。
同步位SYN:SYN=1时表明是一个连接请求或者是连接接收报文。
终止位FIN:FIN=1时表明报文发完,需要释放连接。
窗口(2B):指的是发送方报文段的一方的接收窗口,即允许对方发送的数据量。
检验和(2B):检验首部和数据,检验时要加上12B伪首部(和UDP一样,但是第四个字段中的17改为6)。
紧急指针(2B):只有在URG=1时才有意义,指出本报文段中紧急数据的字节数(位置)。
选项:包括最大报文段长度MSS,窗口扩大,时间戳,选择确认,最大长度可达40B,当没有使用选项时,首部长度为20B。
4.TCP运输连接、释放★★★★★
4.1 TCP连接(三次握手)
一开始,B 的 TCP 服务器进程首先创建传输控制块TCB,准备接受客户端进程的连接请求。然后服务端进程就处于 LISTEN(监听) 状态,等待客户端的连接请求。如有,立即作出响应。
第一次握手:A 的 TCP 客户端进程也是首先创建传输控制块 TCB。然后,在打算建立 TCP 连接时,向 B 发出连接请求报文段,这时首部中的同步位 SYN=1,同时选择一个初始序号 seq = x。TCP 规定,SYN 报文段(即 SYN = 1 的报文段)不能携带数据,但要消耗掉一个序号。这时,TCP 客户进程进入 SYN-SENT(同步已发送)状态。
第二次握手:B 收到连接请求报文后,如果同意建立连接,则向 A 发送确认。在确认报文段中应把 SYN 位和 ACK 位都置 1,确认号是 ack = x + 1,同时也为自己选择一个初始序号 seq = y。请注意,这个报文段也不能携带数据,但同样要消耗掉一个序号。这时 TCP 服务端进程进入 SYN-RCVD(同步收到)状态。
第三次握手:TCP 客户进程收到 B 的确认后,还要向 B 给出确认。确认报文段的 ACK 置 1,确认号 ack = y + 1,而自己的序号 seq = x + 1。这时 ACK 报文段可以携带数据。但如果不携带数据则不消耗序号,这种情况下,下一个数据报文段的序号仍是 seq = x + 1。这时,TCP 连接已经建立,A 进入 ESTABLISHED(已建立连接)状态。
相关面试题:
①为什么两次握手不可以呢?
为了防止已经失效的连接请求报文段突然又传送到了 B,因而产生错误。比如下面这种情况:A 发出的第一个连接请求报文段并没有丢失,而是在网路结点长时间滞留了,以致于延误到连接释放以后的某个时间段才到达 B。本来这是一个早已失效的报文段。但是 B 收到此失效的链接请求报文段后,就误认为 A 又发出一次新的连接请求。于是就向 A 发出确认报文段,同意建立连接。
对于上面这种情况,如果不进行第三次握手,B 发出确认后就认为新的运输连接已经建立了,并一直等待 A 发来数据。B 的许多资源就这样白白浪费了。如果采用了三次握手,由于 A 实际上并没有发出建立连接请求,所以不会理睬 B 的确认,也不会向 B 发送数据。B 由于收不到确认,就知道 A 并没有要求建立连接。
②为什么不需要四次握手?
有人可能会说 A 发出第三次握手的信息后在没有接收到 B 的请求就已经进入了连接状态,那如果 A 的这个确认包丢失或者滞留了怎么办?我们需要明白一点,完全可靠的通信协议是不存在的。在经过三次握手之后,客户端和服务端已经可以确认之前的通信状况,都收到了确认信息。所以即便再增加握手次数也不能保证后面的通信完全可靠,所以是没有必要的。
③Server 端收到 Client 端的 SYN 后,为什么还要传回 SYN?
接收端传回发送端所发送的 SYN 是为了告诉发送端,我接收到的信息确实就是你所发送的信号了。
SYN 是 TCP / IP 建立连接时使用的握手信号。在客户机和服务器之间建立正常的 TCP 网络连接时,客户机首先发出一个 SYN 消息,服务器使用 SYN-ACK 应答表示接收到了这个消息,最后客户机再以 ACK(Acknowledgement[汉译:确认字符,在数据通信传输中,接收站发给发送站的一种传输控制字符。它表示确认发来的数据已经接受无误])消息响应。这样在客户机和服务器之间才能建立起可靠的 TCP 连接,数据才可以在客户机和服务器之间传递。
④传了 SYN,为什么还要传 ACK?
双方通信无误必须是两者互相发送信息都无误。传了 SYN,证明发送方到接收方的通道没有问题,但是接收方到发送方的通道还需要 ACK 信号来进行验证。
4.2 TCP断开(四次挥手)
第二次挥手:B 收到连接释放报文段后立即发出确认,确认号是 ack = u + 1,而这个报文段自己的序号是 v(等于 B 前面已经传送过的数据的最后一个字节的序号加1),然后 B 就进入 CLOSE-WAIT(关闭等待)状态。TCP 服务端进程这时应通知高层应用进程,因而从 A 到 B 这个方向的连接就释放了,这时的 TCP 连接处于半关闭(half-close)状态,即 A 已经没有数据要发送了,但 B 若发送数据,A 仍要接收。也就是说,从 B 到 A 这个方向的连接并未关闭,这个状态可能会持续一段时间。A 收到来自 B 的确认后,就进入 FIN-WAIT-2(终止等待2)状态,等待 B 发出的连接释放报文段。
第三次挥手:若 B 已经没有要向 A 发送的数据,其应用进程就通知 TCP 释放连接。这时 B 发出的连接释放报文段必须使 FIN = 1。假定 B 的序号为 w(在半关闭状态,B 可能又发送了一些数据)。B 还必须重复上次已发送过的确认号 ack = u + 1。这时 B 就进入 LAST-ACK(最后确认)状态,等待 A 的确认。
第四次挥手:A 在收到 B 的连接释放报文后,必须对此发出确认。在确认报文段中把 ACK 置 1,确认号 ack = w + 1,而自己的序号 seq = u + 1(前面发送的 FIN 报文段要消耗一个序号)。然后进入 TIME-WAIT(时间等待) 状态。请注意,现在 TCP 连接还没有释放掉。必须经过时间等待计时器设置的时间 2MSL(MSL:最长报文段寿命)后,A 才能进入到 CLOSED 状态,然后撤销传输控制块,结束这次 TCP 连接。当然如果 B 一收到 A 的确认就进入 CLOSED 状态,然后撤销传输控制块。所以在释放连接时,B 结束 TCP 连接的时间要早于 A。
相关面试题:
①为什么 TIME-WAIT 状态必须等待 2MSL 的时间呢?
a. 为了保证 A 发送的最后一个 ACK 报文段能够到达 B。这个 ACK 报文段有可能丢失,因而使处在 LAST-ACK 状态的 B 收不到对已发送的 FIN + ACK 报文段的确认。B 会超时重传这个 FIN+ACK 报文段,而 A 就能在 2MSL 时间内(超时 + 1MSL 传输)收到这个重传的 FIN+ACK 报文段。接着 A 重传一次确认,重新启动 2MSL 计时器。最后,A 和 B 都正常进入到 CLOSED 状态。如果 A 在 TIME-WAIT 状态不等待一段时间,而是在发送完 ACK 报文段后立即释放连接,那么就无法收到 B 重传的 FIN + ACK 报文段,因而也不会再发送一次确认报文段,这样,B 就无法按照正常步骤进入 CLOSED 状态。
b. 防止已失效的连接请求报文段出现在本连接中。A 在发送完最后一个 ACK 报文段后,再经过时间 2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样就可以使下一个连接中不会出现这种旧的连接请求报文段。
②为什么第二次跟第三次不能合并, 第二次和第三次之间的等待是什么?
当服务器执行第二次挥手之后, 此时证明客户端不会再向服务端请求任何数据, 但是服务端可能还正在给客户端发送数据(可能是客户端上一次请求的资源还没有发送完毕),所以此时服务端会等待把之前未传输完的数据传输完毕之后再发送关闭请求。
5.TCP流量控制
TCP 利用滑动窗口实现流量控制。流量控制是为了控制发送方发送速率,保证接收方来得及接收。接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。
6.TCP拥塞控制
拥塞控制和流量控制不同,前者是一个全局性的过程,而后者指点对点通信量的控制。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫拥塞。
拥塞控制就是为了防止过多的数据注入到网络中,这样就可以使网络中的路由器或链路不致于过载。拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机,所有的路由器,以及与降低网络传输性能有关的所有因素。相反,流量控制往往是点对点通信量的控制,是个端到端的问题。流量控制所要做到的就是抑制发送端发送数据的速率,以便使接收端来得及接收。
为了进行拥塞控制,TCP 发送方要维持一个拥塞窗口(cwnd) 的状态变量。拥塞控制窗口的大小取决于网络的拥塞程度,并且动态变化。发送方让自己的发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。
TCP 的拥塞控制采用了四种算法,即:慢开始、拥塞避免、快重传和快恢复。在网络层也可以使路由器采用适当的分组丢弃策略(如:主动队列管理 AQM),以减少网络拥塞的发生。
a.慢开始:慢开始算法的思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络阻塞,因为现在还不知道网络的符合情况。经验表明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。cwnd 初始值为 1,每经过一个传播轮次,cwnd 加倍。
b.拥塞避免:拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢增大,即每经过一个往返时间 RTT 就把发送方的 cwnd 加 1。
c.快重传与快恢复:在 TCP/IP 中,快速重传和快恢复(FRR)是一种拥塞控制算法,它能快速恢复丢失的数据包。
没有 FRR,如果数据包丢失了,TCP 将会使用定时器来要求传输暂停。在暂停的这段时间内,没有新的或复制的数据包被发送。有了 FRR,如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传这些丢失的数据段。
有了 FRR,就不会因为重传时要求的暂停被耽误。当有单独的数据包丢失时,快速重传和快恢复(FRR)能最有效地工作。当有多个数据信息包在某一段很短的时间内丢失时,它则不能很有效地工作。