运输层协议概述
进程之间的通信
运输层实现的是进程到进程的通信,网络层实现的是主机到主机到通信
从运输层角度上来说,通信的真正端点不是主机而是主机中的进程
复用、分用
复用:不同进程可以使用同一个运输层协议传送数据,即应用进程可以通过运输层再传送到网络层
分用:运输层从 IP层收到发送给应用进程的数据后,必须分别交付给指明的各应用进程
运输层的两个主要协议
- 用户数据报协议UDP,无连接,不可靠交付
- 传输控制协议TCP,面向连接,全双工,可靠
应用层协议 | 运输层协议 |
---|---|
DNS(域名系统) | UDP |
RIP(路由信息协议) | UDP |
DHCP(动态主机配置协议) | UDP |
IGMP(网际组管理协议) | UDP |
SMTP(电子邮件传送协议) | TCP |
HTTP(超文本传送协议) | TCP |
FTP(文件传送协议) | TCP |
端口
运输层使用协议端口号,或简称端口,把端口设为通信的抽象终点
端口只有16位,有65535个不同的端口号
常用的熟知端口:
UDP
UDP的特点
- 无连接,发送数据之前不需要建立连接
- 使用尽最大努力交付,即不保证可靠交付
- 面向报文,UDP对于应用程序交下来的报文,只添加首部后就交付给网络层,因此应用进程必须选择合适大小的报文。
- 没有拥塞控制,网络出现拥挤不会降低主机的发送速度,适合多媒体通信的要求
- 支持一对一、一对多、多对一、多对多
- 首部开销很小,只有8个字节
UDP的首部格式
-
源端口:源端口号,在需要对方回信的时候选用,不需要的时候用全0
-
目的端口:目的端口号,终点交付报文的时候必须使用
-
长度:UDP用户数据报的长度,最小值是8,即只有首部,以字节为单位
-
检验和:检测UDP用户数据报在传输过程中是否出错,出错就丢弃,检测的时候需要加上12字节的伪首部:
计算检验和的方法:把伪首部和UDP数据报连在一起,如果是奇数字节就补一个全0的长度为1字节的数据,然后将其分成若干个长度为2字节的数据,进行二进制反码运算求和,将得出的结果求反码即得到检验和
TCP
主要特点
-
面向连接,在进行传输前必须建立TCP连接,传输完成后要释放TCP连接
-
每条TCP连接只能有两个端点,即只支持点对点
-
可靠交付
-
全双工通信
-
面向字节流
- 流指的是流入或流出进程的字节序列
- TCP将应用层交付的报文看成一串没有结构的字节流,放入发送缓存,TCP传输时每次都是发送一串字节流(长度不定)
- TCP不保证接收方应用程序收到的数据块和发送方应用程序发出的数据块具有对应的大小关系,但是保证发送的字节流一定等于接受的字节流
TCP的连接
TCP连接的端点时套接字socket或者插口
套接字socket = (IP : 端口号)
每一条TCP连接唯一得被通信两端的两个套接字所确定
TCP连接 ::= {socket1,socket2} = {(IP1, port1), (IP2,port2)}
可靠传输
理想传输信道的特点:
- 传输信道不产生差错
- 不管发送方以多快的速度发送数据,接收方总是可以来得及处理数据
停止等待协议
发送方每发送完一个分组就停止发送,一直等到接收方发送了确认报文以后,才继续发送
无差错情况
出现差错(报文丢失、出错)
A发送的报文如果才传输过程丢失了,或检测出差错,则B不会发送确认报文,在超时计时器到期之后,A才会重发
确认丢失和确认迟到
确认指的是接收方发送的确认报文
如果确认报文丢失了,则A未收到确认报文,在超时计时器到期后会再次发送报文,B收到了重复报文后会进行如下两个操作:
- 丢弃这个重复的报文
- 向发送方发送确认报文
如果确认报文迟到了,则 A 在超时计时器到期后重传报文,B 会收到重复的 报文,丢弃重复的报文,并重传确认报文,A 会收到重复的确认。对重复的确认的处理:丢弃
信道利用率
连续ARQ协议
- 发送窗口:发送方维持一个发送窗口,位于发送窗口的分组都可以被连续发送出去,而不需要等待对方的确认
- 发送窗口滑动:发送方每收到一个确认,就把发送窗口向前移动一个分组的位置
- 累计确认:接收方对按序到达的最后一个分组发送确认,表示到这个分组之前的所有分组都已经正确接收
TCP报文段
TCP虽然是面向字节流的,但TCP传送的数据单元仍然是报文段
首部的最小长度是20
-
源端口、目的端口:各占16位
-
序号:占32位,一共232个序号,从0开始用,用于标识字节流中的每一个字节,序号字段的值是本报文段所发送的数据的第一个字节的序号
-
确认号:占4字节,表示期望收到对方的下一个报文段的第一个字节的序号,序号 = n,则表明到n-1的字节都已经收到了
-
数据偏移:即首部长度,4位,单位为4字节,最多表示15,所以TCP首部最长是60字节
-
保留
-
紧急URG:控制位,URG = 1,表示紧急指针字段有效,告诉系统此报文中有紧急数据,应尽快传送
-
紧急指针:占16位,指出紧急数据的末尾在报文段中的位置
-
确认ACK:控制位,ACK = 1时确认号有意义,否则确认号无效
-
推送PSH:控制位,PSH = 1的报文段应尽快交付应用进程
-
复位RST:控制位,RST = 1表明TCP连接出现严重差错,必须释放连接然后重新建立连接
-
同步SYN:控制位:SYN = 1表示是连接请求或连接接收报文
- SYN = 1,ACK = 0,是连接请求
- SYN = 1,ACK = 1,是连接接收
-
终止FIN:控制位,FIN = 1 表明此报文段的发送端的数据已经发送完毕,并要求释放运输连接
-
窗口:占16位,指出了现在允许对方发送的数据量,动态变化
-
检验和:占16位,检验范围包括伪首部、首部、数据这三部分,同UDP
-
填充:使整个TCP首部长度是4字节的整数倍
-
选项:长度可变,最长可以是40字节
-
MSS:TCP数据字段的最大长度,与接收窗口值无关,不能太大也不能太小,在允许的范围内尽可能大,要使得在IP层传输时不再分片,默认值是536字节
TCP报文长度 = 536 + 20
IP数据报长度 = 536 + 20
-
窗口扩大:TCP窗口字段 = 16字节,最大窗口大小 = 64K字节,对于大传播时延、大带宽的网络,为了获得较高吞吐率,需要大窗口,占3字节,表示的是位移值S,即16->16+S,位移最大可以是14,即最大窗口是230-1
-
时间戳:占10字节,包括4字节的时间戳字段和4字节的时间戳回送回答和其他
主要功能:
- 计算RTT
- 防止序号绕回
-
以字节为单位的滑动窗口
发送窗口
A根据B给出的窗口值,构造出自己的发送窗口
发送窗口里的序号表示允许发送的数据的序号
当A接收到了B发送来的确认报文,才能根据接收报文来移动P1
发送窗口内的数据必须放在发送缓存中,以防对方没收到需要进行重传
接收窗口
发送的确认序号永远是第一个没收到的序号
超时重传时间的选择
加权平均往返时间RTTS
新的RTTS = 0.875 * 旧的RTTS + 0.125 * 新的RTT样本
RTT的偏差加权平均值RTTD
RTTD = 0.75 * RTTD + 0.25 * |新的RTTS – 新的RTT样本|
超时重传时间RTO
RTO = RTTS + 4 * RTTD
Karn算法
计算平均往返时间RTT时,只要报文段重传了,则不采用其RTT样本
报文段每重传一次,就把RTO = RTO * 2
利用滑动窗口实现流量控制
流量控制:
让发送方的发送速率不要太快,使接收方来得及接收
接收窗口rwnd
持续计时器
只要TCP连接的一方接收到对方的零窗口通知,就启动该计时器
- 若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带1 字节的数据),对方在确认这个探测报文段时给出当前窗口值。
- 若窗口仍然是零,收到这个报文段的一方就重新设置持续计时器。
- 若窗口不是零,则死锁的僵局就可以打破了。
TCP的传输效率
TCP发送报文段的时机
三种机制:
- 维持一个变量,当发送缓存的数据达到MSS就发送
- 当发送方的进程指明要求发送数据,即TCP的推送操作
- 发送方的一个计时器到期了,就发送
糊涂窗口综合症
每次只发送一个字节或很少的字节,使得传输效率很低
发送方糊涂窗口综合症
解决方法:Nagle算法
先发送一个字节的报文,当发送方对第一个数据字符进行确认后,再把缓存中的所有数据组成报文发出去,等待下一个确认报文到达后再如此发送
Nagle算法也规定了,当到达的数据达到发送窗口大小的一半或已经达到MSS时,就立即发送一个报文段
接收方糊涂窗口综合症
原因:接收方应用进程消耗数据太慢,例如每次只读取一个字节
解决方法:让接收方等待一段时间,使得或者接收缓存已有足够空间容纳一个最长的报文段,或者等到接收缓存已有一半空闲的空间。只要出现这两种情况之一,接收方就发出确认报文,并向发送方通知当前的窗口大小
拥塞控制
在某段时间,省对网络中某资源的需求超过了该资源所能提供的可用部分,网络的性能就要明显变坏,整个网络的吞吐量将随输入负荷的增大而下降。这种现象称为拥塞 (congestion)。
出现拥塞的条件:
- 拥塞控制的前提:网络能够承受现有的网络负荷。
- 实践证明,拥塞控制是很难设计的,因为它是一个动态问题。
- 分组的丢失是网络发生拥塞的征兆,而不是原因。
- 在许多情况下,甚至正是拥塞控制本身成为引起网络性能恶化、甚至发生死锁的原因。
开环控制
在设计网络时,事先考虑周全,力求工作时不发生拥塞。
思路:力争避免发生拥塞。
旦一旦整个系统运行起来, 就不再中途进行改正了。
闭环控制
基于反馈环路的概念。
根据网络当前运行状态采取相应控制措施。
思路:在发生拥塞后,采取措施进行控制,消除拥塞。
TCP的拥塞控制方法
- TCP采用基于滑动窗口的方法进行拥塞控制,属于闭环控制方法
- TCP发送方维持一个拥塞窗口cwnd
- cwnd的大小取决于网络的拥塞程度,动态变化
- 发送端根据cwnd调制数据发送量
发送窗口 = min(cwnd, rwnd)
判断拥塞的方法:
- 超时重传计时器超时:网络已经出现拥塞
- 收到3个重复的确认:预示网络可能会出现拥塞
拥塞控制算法
慢开始
-
目的:探测网络的负载能力或拥塞程度
-
算法:由小到大逐渐增大cwnd
-
2个控制变量:
- 拥塞窗口cwnd,初始为1
- 慢开始门限ssthresh
每收到一个对新的报文段的确认,就把拥塞窗口+1
传输轮次
- 一个传输轮次所经历的时间其实就是往返时间 RTT。
- 传输轮次强调:把拥塞窗口 cwnd 所允许发送的报文段都连续发送出去,并收到了对己发送的最后一个字节的确认。
- 例如:拥塞窗口 cwnd=4,这时的往返时间 RTT 就是发送方连续发送4个报文段,并收到这 4 个报文段的确认,总共经历的时间。
慢开始门限ssthresh
- 当cwnd < ssthresh时,使用慢开始算法
- 当cwnd > ssthresh时,使用拥塞避免算法
- 当cwnd = ssthresh时,用慢开始或者拥塞避免
拥塞避免
每经过一个RTT,cwnd = cwnd + 1
一旦发生超时计时器超时,则:
- ssthresh = max(2, cwnd / 2)
- cwnd = 1
- 执行慢开始算法
快重传
发送方只要收到三个重复的确认,即立刻进行重传,防止超时
快恢复
当收到三个重复的确认,不执行慢开始算法,而是执行快恢复算法:
- ssthresh = cwnd / 2
- cwnd = cwnd / 2
- 执行拥塞避免
TCP连接建立的过程
采用三报文握手
- TCP服务器先创建传输控制块TCB,准备接收客户进程的连接请求,这是被动打开
- 用户TCP向服务器主动发出连接请求报文,SYN = 1,并选择序号seq = x,表明传送数据的第一个数据字节的序号是x
- 服务器收到连接请求报文后,如果同意,则发确认报文,SYN = 1,ACK = 1,选择序号为seq = y,ack = x + 1
- 客户端收到连接确认报文后,发送普通报文给服务器,ACK = 1,seq = x + 1, ack = y + 1
- 进行数据传送
问题:TCP为什么进行三次握手?两次可以吗
如果A发出的第一个链接请求在网络中长时间滞留,A会重传连接请求。如果A重传的连接请求完成了建立连接,数据传送后释放了连接后,A发出的第一个链接请求到达了B,虽然这个连接请求己失效,但 B误认为A重新发起的新连接,于是给A回复ACK报文。如果没有第三次握手,那么这个过期的链接申请就可以建立连接,对网络资源是一种浪费。
TCP连接释放
采用四报文挥手
- A的应用进程先向其TCP发出连接释放报文段,并停止发送数据,主动关闭TCP连接,FIN = 1,seq = u,等待b的确认
- B收到TCP连接释放报文后,发出TCP连接释放确认报文,ACK = 1,ack = u + 1,seq = v。此时TCP服务器通知高层应用进程,A到B这个方向的连接就释放了,选择处于半关闭状态,但如果B要发送数据,A还有接收
- 等B没有数据要发送时,其应用进程就通知服务器TCP释放连接,这是被动过程,B向A发送TCP连接释放报文,FIN = 1,ACK = 1, ack = u + 1,seq = w
- A收到连接释放报文后,发出连接释放确认报文,ACK = 1,ack = w + 1,seq = u + 1
当A收到B的TCP连接释放报文后,要经过时间等待计时器设置的2MSL后,A才释放TCP连接,这是为了防止B没收到A的连接释放确认报文,以及防止已失效的连接请求报文出现在本连接中,而B在收到后连接释放确认报文后就直接关闭
保活计时器
用来防止在TCP连接出现长时期的空闲,通常设置为2小时
若服芳器过了2小时还没有收到客尸时信息,己就发送探测报文段。
若发送了 10 个探测报文段(每一个相隔75秒)还没有响应,就假定客户出了故障,因而就终止该连接。