运输层
一、运输层的基本概念
从通信和信息处理的角度看,运输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能中的最低层。只有位于网络边缘部分的主机的协议栈才有运输层,而网络核心部分中的路由器在转发分组时都只用到下三层的功能。
在一台主机中经常有多个应用进程同时分别和另一台主机中的多个应用进程通信。
这表明运输层有一个很重要的功能——复用 (multiplexing)和分用 (demultiplexing)。
1.1端口的概念
从IP层来说,通信的两端是两台主机。
从运输层的角度看,通信的真正端点并不是主机而是主机中的进程。端到端的通信是应用进程之间的通信。
也就是说:运输层主要是处理进程之间的通信的,而端口就代表了进程。
端口用一个 16 位端口号进行标志。
端口号只具有本地意义,即端口号只是为了标志本计算机应用层中的各进程。
由此可见,两个计算机中的进程要互相通信,不仅必须知道对方的 IP 地址(为了找到对方的计算机),而且还要知道对方的端口号(为了找到对方计算机中的应用进程)。
1.2屏蔽作用
运输层向高层用户屏蔽了下面网络核心的细节(如网络拓扑、所采用的路由选择协议等),它使应用进程看见的就是好像在两个运输层实体之间有一条端到端的逻辑通信信道。(这也是分层的好处)
二、两种不同的运输协议TCP、UDP
当运输层采用面向连接的 TCP 协议时,尽管下面的网络是不可靠的(只提供尽最大努力服务),但这种逻辑通信信道就相当于一条全双工的可靠信道。
当运输层采用无连接的 UDP 协议时,这种逻辑通信信道是一条不可靠信道。
两个对等运输实体在通信时传送的数据单位叫作运输协议数据单元 TPDU (Transport Protocol Data Unit)。
2.1UDP
UDP 只在 IP 的数据报服务之上增加了很少一点的功能:
复用和分用的功能
差错检测的功能
UDP特性:
提供无连接服务。
在传送数据之前不需要先建立连接。
传送的数据单位协议是 UDP 报文或用户数据报。
对方的运输层在收到 UDP 报文后,不需要给出任何确认。
虽然 UDP 不提供可靠交付,但在某些情况下 UDP 是一种最有效的工作方式。
UDP 支持一对一、一对多、多对一和多对多的交互通信。
UDP 的首部开销小,只有 8 个字节,比 TCP 的 20 个字节的首部要短
还要注意的是:
IP 数据报要经过互连网中许多路由器的存储转发。
UDP 用户数据报是在运输层的端到端抽象的逻辑信道中传送的。
UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。应用层交给 UDP 多长的报文,UDP 就照样发送,即一次发送一个报文。
2.1.1UDP 的首部格式
在计算检验和时,临时把“伪首部”和 UDP 用户数据报连接在一起。伪首部仅仅是为了计算检验和。
请注意,虽然在 UDP 之间的通信要用到其端口号,但由于 UDP 的通信是无连接的,因此不需要使用套接字。
2.2TCP
面向字节流
TCP 中的“流”(stream)指的是流入或流出进程的字节序列。
“面向字节流”的含义是:虽然应用程序和 TCP 的交互是一次一个数据块,但 TCP 把应用程序交下来的数据看成仅仅是一连串无结构的字节流。
接收方应用程序收到的字节流必须和发送方应用程序发出的字节流完全一样。
提供面向连接的服务。
传送的数据单位协议是 TCP 报文段 (segment)。
TCP 不提供广播或多播服务。
由于 TCP 要提供可靠的、面向连接的运输服务,因此不可避免地增加了许多的开销。这不仅使协议数据单元的首部增大很多,还要占用许多的处理机资源。
TCP 报文段是在运输层抽象的端到端逻辑信道中传送,这种信道是可靠的全双工信道。但这样的信道却不知道究竟经过了哪些路由器,而这些路由器也根本不知道上面的运输层是否建立了 TCP 连接。
值得注意的点:
TCP 连接是一条虚连接而不是一条真正的物理连接。
TCP 对应用进程一次把多长的报文发送到TCP 的缓存中是不关心的。
TCP 根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节(UDP 发送的报文长度是应用进程给出的)
2.2.1套接字的概念
在TCP中,面向的既不是IP,又不是端口,它面向的是套接字。
TCP 连接的端点叫做套接字 (socket) 或插口。
端口号拼接到 (contatenated with) IP 地址即构成了套接字。
2.2.2TCP 报文段的首部格式
TCP 虽然是面向字节流的,但 TCP 传送的数据单元却是报文段
TCP 报文段首部的前 20 个字节是固定的,后面有 4n 字节是根据需要而增加的选项 (n 是整数)。因此 TCP 首部的最小长度是 20 字节。
2.2.3可靠传输的原理
理想的传输条件有以下两个特点:
(1) 传输信道不产生差错。
(2) 不管发送方以多快的速度发送数据,接收方总是来得及处理收到的数据。
然而实际的网络都不具备以上两个理想条件。必须使用一些可靠传输协议,在不可靠的传输信道实现可靠传输。
那么在TCP中就有两种方式来实现可靠传输了
停止等待协议
连续 ARQ 协议
2.2.3.1停止等待协议
“停止等待”就是每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组。
停止等待协议有两种情况:
无差错情况
出现差错
在接收方 B 会出现两种情况:
B 接收 M1 时检测出了差错,就丢弃 M1,其他什么也不做(不通知 A 收到有差错的分组)。
M1 在传输过程中丢失了,这时 B 当然什么都不知道,也什么都不做。
解决:
A 为每一个已发送的分组都设置了一个超时计时器。
A 只要在超时计时器到期之前收到了相应的确认,就撤销该超时计时器,继续发送下一个分组 M2 。
值得注意的是:
在发送完一个分组后,必须暂时保留已发送的分组的副本,以备重发。
分组和确认分组都必须进行编号。
超时计时器的重传时间应当比数据在分组传输的平均往返时间更长一些。
像上述的这种可靠传输协议常称为自动重传请求 ARQ (Automatic Repeat reQuest)。意思是重传的请求是自动进行的,接收方不需要请求发送方重传某个出错的分组。
为了提高传输效率,发送方可以不使用低效率的停止等待协议,而是采用流水线传输。
流水线传输就是发送方可连续发送多个分组,不必每发完一个分组就停顿下来等待对方的确认。这样可使信道上一直有数据不间断地传送。
2.2.3.2连续 ARQ 协议
发送方维持的发送窗口,它的意义是:位于发送窗口内的分组都可连续发送出去,而不需要等待对方的确认。这样,信道利用率就提高了。
连续 ARQ 协议规定,发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置。
即不必对收到的分组逐个发送确认,而是对按序到达的最后一个分组发送确认,这样就表示:到这个分组为止的所有分组都已正确收到了。
优点:容易实现,即使确认丢失也不必重传。
缺点:不能向发送方反映出接收方已经正确收到的所有分组的信息。
如果发送方发送了前 5 个分组,而中间的第 3 个分组丢失了。这时接收方只能对前两个分组发出确认。发送方无法知道后面三个分组的下落,而只好把后面的三个分组都再重传一次。
这就叫做 Go-back-N(回退 N),表示需要再退回来重传已发送过的 N 个分组。
具体实现:
TCP 连接的每一端都必须设有两个窗口——一个发送窗口和一个接收窗口。
TCP 的可靠传输机制用字节的序号进行控制。TCP 所有的确认都是基于序号而不是基于报文段。
TCP 两端的四个窗口经常处于动态变化之中。
TCP连接的往返时间 RTT 也不是固定不变的。需要使用特定的算法估算较为合理的重传时间。
三、常用熟知的端口
四、TCP 的拥塞控制
出现拥塞的原因:
对资源需求 > 可用资源
即使增大资源也不是能解决拥塞的问题的。不但不能解决拥塞问题,而且还可能使网络的性能更坏。
拥塞引起的重传并不会缓解网络的拥塞,反而会加剧网络的拥塞。因为会引起更多的分组流入网络和被网络中的路由器丢弃。
4.1拥塞控制的作用
为了提高我们的资源利用率,避免发生死锁问题。
4.2流量控制和拥塞控制的区别
拥塞控制:
拥塞控制是一个全局性的过程,涉及到所有的主机、所有的路由器,以及与降低网络传输性能有关的所有因素。
拥塞控制就是防止过多的数据注入到网络中,使网络中的路由器或链路不致过载。
流量控制:
流量控制往往指点对点通信量的控制,是个端到端的问题(接收端控制发送端)。
流量制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收。
4.3TCP 的拥塞控制方法
开环控制方法就是在设计网络时事先将有关发生拥塞的因素考虑周到,力求网络在工作时不产生拥塞。
闭环控制方法是基于反馈环路的概念。属于闭环控制的有以下几种措施:
(1) 监测网络系统以便检测到拥塞在何时、何处发生。
(2) 将拥塞发生的信息传送到可采取行动的地方。
(3) 调整网络系统的运行以解决出现的问题。
TCP 采用基于窗口的方法进行拥塞控制。该方法属于闭环控制方法。
只要网络没有出现拥塞,拥塞窗口就可以再增大一些,以便把更多的分组发送出去,这样就可以提高网络的利用率。
但只要网络出现拥塞或有可能出现拥塞,就必须把拥塞窗口减小一些,以减少注入到网络中的分组数,以便缓解网络出现的拥塞。
拥塞的判断:
重传定时器超时
收到三个相同(重复)的 ACK
TCP拥塞控制算法:
慢开始 (slow-start)
拥塞避免 (congestion avoidance)
快重传 (fast retransmit)
快恢复 (fast recovery)
五、TCP三次握手协议
TCP 建立连接的过程叫做握手。
握手需要在客户和服务器之间交换三个 TCP 报文段。称之为三报文握手。
采用三报文握手主要是为了防止已失效的连接请求报文段突然又传送到了,因而产生错误。
过程:
A 的 TCP 向 B 发出连接请求报文段,其首部中的同步位 SYN = 1,并选择序号 seq = x,表明传送数据时的第一个数据字节的序号是 x。
B 的 TCP 收到连接请求报文段后,如同意,则发回确认。B 在确认报文段中应使 SYN = 1,使 ACK = 1,其确认号ack = x+1,自己选择的序号 seq = y。
A 收到此报文段后向 B 给出确认,其 ACK = 1,确认号 ack = y + 1。A 的 TCP 通知上层应用进程,连接已经建立。
B 的 TCP 收到主机 A 的确认后,也通知其上层应用进程:TCP 连接已经建立。
六、TCP释放连接
过程:
现在 A 的应用进程先向其 TCP 发出连接释放报文段,并停止再发送数据,主动关闭 TCP 连接。A 把连接释放报文段首部的 FIN = 1,其序号seq = u,等待 B 的确认。
B 发出确认,确认号 ack = u + 1,而这个报文段自己的序号 seq = v。TCP 服务器进程通知高层应用进程。从 A 到 B 这个方向的连接就释放了,TCP 连接,处于半关闭状态。B 若发送数据,A 仍要接收。
若 B 已经没有要向 A 发送的数据,其应用进程就通知 TCP 释放连接。
A 收到连接释放报文段后,必须发出确认。
在确认报文段中 ACK = 1,确认号 ack = w + 1,自己的序号 seq = u + 1。
A 必须等待 2MSL 的时间:
第一,为了保证 A 发送的最后一个 ACK 报文段能够到达 B。
第二,防止 “已失效的连接请求报文段”出现在本连接中。A 在发送完最后一个 ACK 报文段后,再经过时间 2MSL,就可以使本连接持续的时间内所产生的所有报文段,都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。
最后
如果大家有更好的理解方式或者文章有错误的地方还请大家不吝在评论区留言,大家互相学习交流~~~
如果想看更多的原创技术文章,欢迎大家关注我的微信公众号:Java3y。Java技术群讨论:742919422。公众号还有海量的视频资源哦,关注即可免费领取。
可能感兴趣的链接:
文章的目录导航(微信公众号端):https://zhongfucheng.bitcron.com/post/shou-ji/wen-zhang-dao-hang
文章的目录导航(PC端):http://www.zhongfucheng.bitcron.com/post/shou-ji/pcduan-wen-zhang-dao-hang
海量精美脑图:http://www.zhongfucheng.bitcron.com/post/shou-ji/nao-tu-da-quan