浅谈计算机网络之传输层TCP,UDP协议

概述

运输层向应用层提供通信服务,两个主机进行通信其实是运行在两个主机上的进程进行通信,网络层使用的IP协议只负责把分组传送到目的主机,运输层负责交付到应用进程。
运输层提供两个重要的功能:1.复用,2.分用
复用:指在发送方不同的应用进程可以使用同一个运输层协议传输数据
分用:指在接收方运输层在剥去报文首部之后能够交付给目的进程
运输层有两个主要协议:TCP,UDP,下面详细探讨这两个运输层协议。

端口

在探讨TCP,UDP之前先简单说一个端口。端口分为硬件端口和软件端口。
硬件端口:不同硬件设备进行交互的接口
软件端口:应用层的各种协议进程与运输实体进行层间交互的一种地址
下面我们讲的是软件端口

TCP/IP运输层用一个16位端口号来标志一个端口

端口只具有本地意义,16位端口允许有2^16=65535个端口号,对于一台计算机来说已经够用了。
熟知端口号: 数值为0~1023

应用程序FTPTELNETSMTPDNSTFTPHTTPSNMPSNMP
熟知端口号212325536980161162

登记端口号: 数值为1024—49152
客户端选择使用的端口号: 数值为49152—65535
客户进程运行时才动态选择,也叫短暂端口号
当服务器收到客户端发送的报文之后,服务器就知道了客户端所使用端口号,因而可以把数据发送给客户进程

用户数据报协议UDP

由于UDP比较简单,所以我们先讲UDP。
UDP的6大特点:
1.UDP是无连接的,也就是说发送之前不需要先建立连接,减少了开销和发送数据之前的时延
2.UDP是尽最大努力交付的,也就是说不提供可靠交付服务
3.UDP是面向报文的,也就是说收到应用层传送下来的报文在添加首部之后就直接交付IP层,不会像IP层那样,如果数据报太长就采用分组
4.UDP没有拥塞控制,网络拥塞时不会影响发送速率(发送数据速率恒定),允许网络拥塞时丢失一些数据,但不允许时延大(适合IP电话,视频服务应用)
5.UPD支持一对一,一对多,多对一
6.首部开销小,只有8个字节,2个字节源端口号(不需要使用时全为0),2个字节目的端口号,2个字节报文长度(最少为8,只有首部的情况下),2个字节校验和(校验数据报是否出错,出错就丢弃,也可递交给应用层并附上错误警告),相比TCP20个字节的首部较小
如果接受方UDP发现收到的报文目的端口不正确(本地不存在对应端口的应用进程),就丢弃该报文,并由网际控制协议ICMP发送“端口不可达”差错报文给发送方

UDP数据报校验和的计算

1.在UDP数据报前面添加12个字节的伪首部,4个字节的(源IP地址),4个字节的(目的IP地址),1字节0,1字节17,2字节UDP长度
2.伪首部不向下传递,也不向上提交,仅仅只是为了计算校验和
3.校验和计算方法与IP数据报首部校验和的方法类似,区别在于IP数据报校验和只校验首部,而UDP数据报的校验和是吧首部和数据部分一起校验的,校验步骤如下
在发送方
把全0填入校验和字段
把伪首部和UDP数据报看成是N个16位字串接起来的
如果数据部分不是偶数字节,则用0填充(此部分是不发送的)
将每16位看成一个数字,二进制求和之后,这个和的反码就是校验和
在接收方
把收到的UDP数据报连同伪首部以及可能填充的全0字段一起按二进制反码求这些16位字的和,如果无差错应该全为1,否则代表出错

传输控制协议TCP

TCP的5大特点:
1.面向连接的,也就是说进行传输之前需要建立连接,传输结束之后释放连接
2.只能有两个端点,所以只支持一对一
3.提供可靠交付服务(无差错,不重复,不丢失,按序到达)
4.TCP提供全双工通道(TCP连接的两端都设有发送缓存区和接收缓存区,应用层只需要负责把字节数据块(n个字节的数据)交给发送缓存区就可以了)
5.面向字节流
与UDP发送报文采取的方式完全不同,UDP报文的长度是由应用层决定的,TCP报文的长度是由接收方给出的窗口值和网络拥塞程度决定的,也就是说如果应用层一次只发来一个字节的数据,TCP可以在发送缓存区积累到足够多的字节后再构成TCP报文发送出去

TCP的链接

TCP连接的两个端点不是端口号也不是IP地址,而是叫套接字socket=(IP地址:端口号)
TCP连接::={socket1,socket2} = {(IP1:port1),(IP2:port2)}
同一个socket名词可以表示多种不同的意思

可靠传输的工作原理

停止等待协议:
“停止等待”指的是每发送一个分组就停止发送,等待对方确认,收到确认之后再发送下一个分组(效率低)
1.无差错情况
发送方每发送一个分组,接收方就收到这个分组并发送确认报文,发送方收到确认报文,继续发送新的分组,如此反复。
2.出现差错情况
收到差错报文就丢弃,然后什么也不做(不用告诉发送方有差错),发送方超时还没收到接收方的确认报文就重新发送,这就叫超时重传
在发送完分组之前先备份这个分组(为了超时可以重传),在发送完分组之后马上设置一个超时计时器,如果未超时收到确认报文就撤销这个计时器和删除备份分组
3.确认丢失和确认迟到
如果接受方正常收到分组并对发送方发送确认分组,发送方迟迟没有收到这个确认分组触发了超时重传,接收方又收到这个分组(重复的分组),那么就丢弃,并再次发送确认分组,然后发送方将会收到2个确认分组,第一个收下,第二个发现重复了就丢弃
正常不会存在A无限的给B发送分组,B收到分组并发送了确认分组,但A一直收不到,因为B能收到A的分组说明通信线路不差
确认重传机制使得在不可靠的传输网络上实现了可靠传输,这种确认重传机制使用到的可靠协议称为自动重传请求ARQ

连续ARQ协议

滑动窗口协议比较复杂,是TCP协议的精髓所在

TCP报文段首部格式

固定部分20个字节

  1. 2个字节源端口,2个字节目的端口
  2. 4个字节序号,本TCP报文所发送的数据的第一个字节的序号(范围是0~232-1,当序号增加到232-1时下个序号又是0,也就是说序号使用的是mod2^32运算,TCP是面向字节流的,每个字节都按序编号,始序号在建立连接时设置)
  3. 4个字节确认号
  4. 4位数据偏移,数据部分距离起始位置有多远,也就是首部长度,单位是32位(4个字节),最大值是15,也就是首部最长为60个字节,固定部分占20个字节,所以首部可选部分最长40个字节
  5. 6位保留,今后使用,全置为0
  6. 1位紧急URG,为1时,表明紧急指针有效
  7. 1位确认ACK,为1时,确认号才有效,TCP规定,在连接建立后所有传送的报文段都必须吧ACK置为1
  8. 1位推送PSH,接收方收到PSH为1的报文时,就尽快的交付接收应用进程,而不用等到整个缓存填满了再向上交付
  9. 1位复位RST,为1时表明TCP连接出现了严重错误,需要释放连接然后再重新建立连接。RST为1还可以用来拒绝一个非法报文或者拒绝打开一个连接。
  10. 1位同步SYN,为1而ACK为0时表明这是一个连接请求报文。SYN和ACK都为1时表明这是一个连接请求或连接接收报文。
  11. 1位终止FIN,用来释放一个连接,当值为1时,表明发送方数据已经发送完毕,并要求释放运输连接
  12. 窗口
  13. 2个字节检验和
  14. 2个字节紧急指针,当URG为1时有效
  15. 选项,可变长度最长40个字节

可变长度4N个字节,上面有提到首部长度字段只有4位,最大值就是15,单位为4个字节,所以首部最长为60个字节,固定部分占20个字节,所以可变长度最长只有40个字节

TCP可靠传输的实现(A:发送方,B:接收方)
  1. 在未收到B的确认报文之前,A的发送窗口里所有的数据都可以发送出去
  2. 收到B的确认之后,A根据确认报文中的窗口值进行调整,扩大,不变,缩小(TCP标准强烈不赞成这样做,因为A在收到确认报文之前可能把发送窗口里的许多数据,如果因为缩小窗口不让发送这些数据,就会产生错误)
  3. A发送完未收到确认的数据继续留在发送窗里(因为可能发生错误需要重传)
  4. A发送完已经收到确认的数据就从发送缓存中删除
  5. B接受到未按序到达的数据就留在接受窗口
  6. B拥有累计确认的功能,这样可以减少开销,在适当的时候发送确认报文,有时候还可以在有其他数据需要发送时捎带确认信息,但是很少会这样使用
超时重传的选择

报文往返时间RTT
加权往返时间RTTs=(1-a)x旧的RTTs+ax新的RTTs,RFC2988推荐a=0.125
RTT的偏差加权值RTTD=(1-b)x旧的RTTD+bx|RTTs-新的RTT样本|
超时重传时间RTO,RFC2988建议等于RTTs+4xRTTD

选择确认SACK

重传能否只传缺少的数据而不重传已经正确到达接收方的数据,使用选择确认SACK就可以
使用方法如下

  1. 建立TCP连接,就在TCP首部的选项中加上允许SACK的选项
  2. 在之后的TCP报文中都会增加SACK选项用于报告收到的不连续的字节块边界

目前SACK并没有规定发送方怎么响应SACK,因此目前还是重传所有未被确认的数据块

TCP的流量控制

流量控制就是要让发送方不要发送太快,要让接收方来得及接收

利用滑动窗口实现流量控制

发送方的发送窗口不能超过接收方给出的接收窗口的数值(窗口的单位是字节,不是报文段)

持续计时器:只要TCP其中一方收到对方的0窗口通知,那就会启动持续计时器,当持续计时器的时间到期,就会发送一个0窗口探测报文(携带一个字节数据),对方在收到这个0窗口探测报文之后给出现在的窗口值,如果还是0,那么就重新设置持续计时器继续等待,如果不为0,那么就可以继续发送报文(死锁被打破)

考虑传输效率

发送方收到应用进程把数据传送到TCP的发送缓存之后,剩下的任务就交给TCP了。
TCP缓存在收到应用进程发送过来的数据不会马上就发送出去,而是依靠三种不同的机制来控制发送

  1. TCP维持一个变量,它等于最大报文长度MSS。只要缓存中存放的数据达到MSS字节就发送
  2. 收到的应用进程发送来的数据指明要求发送报文,那么TCP就会马上组装成一个PSH字段为1的TCP报文发送出去
  3. 发送方的一个计时器期限到就发送(这个时候长度肯定不会超过MSS)
    但是如何控制发送时机还是个很复杂的问题

在TCP的实现中广泛使用Nagle算法,算法如下

  1. 发送方先把第一个字节发送出去,等待确认再把发缓存中所有的数据组装成一个报文发送出去,同时继续对随后到达TCP缓存的数据进行缓存,只有在收到前一个报文的确认后才继续发送下一个报文段
  2. 如果到达的数据已经到达发送窗口大小的一半或者已达到报文段的最大限时,就立即发送一个报文段,提高吞吐量

糊涂窗口综合症

发生于TCP接收方的接受缓存满了,而且交互的应用进程一次只从接受缓存读取一个字节(这样接受缓存就腾出了一个字节的空间),然后向发送方发送确认报文中窗口值为1,如此反复使网络的效率变得很低

解决糊涂窗口综合症的方法

让发送方不发送很小的报文段,接收方在接收缓存空间还剩很少的情况下就像发送方发送确认报文(让接受方等待一段时间,或者等到缓存有了一半以上的空闲空间)

TCP的拥塞控制

拥塞控制的一般原理

拥塞控制就是防止过多的数据注入到网络中,使网络中的路由器和链路不致过载。
为什么不能让过多的数据注入到网络中呢?
假设过多的数据注入到网络中,那么路由器有可能因为缓存太小而导致后面数据到达该路由器因为无存储空间而不得不丢弃。如果只是把缓存扩大到很大,那么会导致在路由器缓存的数据队列太长,路由器还没来得及处理发送方的重传计时器就到期了而触发了超时重传,这样就使网络的负载越来越大,吞吐量越来越小,当吞吐量为0时,网络就无法工作,这就是所谓的死锁。所以只有所有的部分得到平衡了才能解决网络拥塞的问题。

几种拥塞控制的方法

慢开始和拥塞避免

发送方维持一个拥塞窗口cwnd状态变量,值的大小决定网络的拥塞程度,并且是动态变化的。
慢开始:
先把拥塞窗口设置为一个最大报文段MSS的数值,发送第一个报文段M1,等收到确认报文之后就把cwnd的值从1增大到2,接着发送报文段M2,M3,等接收到M2,M3的确认报文之后就把cwnd的值从2增大到4,也就是每经过一个传输轮次,cwnd就增大一倍。
拥塞避免:
为了防止cwnd增大过大,所以设置了一个慢开始门限ssthresh,当cwnd < ssthresh时使用慢开始算法,当cwnd > ssthresh时使用拥塞避免算法,当cwnd = ssthresh时两者都可以使用。
拥塞避免算法的思路是让cwnd增大缓慢一点,每经过一个传输轮次,cwnd就加1(慢开始算法是增大一倍)
当发送方没有按时收到确认报文时就认为网络出现拥塞,当网络出现拥塞就把ssthresh设置为cwnd的一半(但不小于2),然后把cwnd重新设置为1。这两种算法合起来成为AIMD算法,这种算法被广泛使用。
如下图:
在这里插入图片描述

快重传和快恢复

快重传:
当接收方每收到一个失序的报文段就立即发出重复确认,当发送方连续收到三个重复确认就应当立即重传接收方尚未接收的报文段,而不必等待重传计时器到期。
例如:发送方发送5个报文段M1,M2,M3,M4,M5,接收方接收到了M1,接着如果接收到的不是M2而是M3那么就立即发送M1的确认,接着如果接收到的不是M2而是M4那么就立即发送M1的重复确认,接着如果接收到的不是M2而是M5那么就立即发送M1的确认,此时发送方若连续收到3个对M1的确认,那么就认为M2已经丢失然后立即重新发送M2,而不必等待M2的重传计时器到期再触发M2的重传。
快恢复:
快恢复是和快重传搭配使用的算法,当发送方连续接收到3个重复确认后,就把ssthresh和cwnd的值设置为cwnd的一半,然后使用拥塞避免算法。
如下图:
在这里插入图片描述
注意,上面讲的都是假设接收窗口足够大的情况,实际情况是发送窗口一定不能大于接收窗口rwnd,也就是
发送窗口=min[cwnd,rwnd]

TCP的运输连接管理

TCP连接分三个阶段

  1. 建立连接
  2. 数据传送
  3. 释放连接

建立连接

  1. B先创建一个传输控制模块TCB,进入listen(监听)状态
  2. A也创建一个传输控制模块TCP,向B发送一个请求报文,这个报文首部SYN为1,ACK为0,不携带数据,占用一个序号,进入同步SYN-SEND(同步已发送)状态
  3. B收到请求报文之后,如果同意建立连接,则向A发送确认报文,这个报文首部SYN为1,不携带数据,占用一个序号,进入同步SYN-RCVD(同步已接收)状态
  4. A收到确认报文之后也要向B发送确认报文,这个报文可以携带数据,如果不携带数据不占用序号

步骤2,3,4称为3次握手
问题:为什么需要步骤4呢?如果没有步骤4会有什么异常情况?

释放连接

  1. A数据传输完之后,向B发送一个释放连接报文,这个报文的首部FIN为1,不携带数据,占用一个序号,A进入终止等待状态1
  2. B收到释放连接报文之后,向A发送确认报文,B进入关闭等待状态,这时TCP连接进入半关闭状态
  3. 如果B需要向A传输数据,A仍要接收,A进入终止等待状态2
  4. 如果B不需要向A传输数据,那么向A发送一个释放连接报文,这个报文首部FIN为1,不携带数据,占用一个序号,B进入最后等待状态
  5. A收到B的释放连接报文之后,向B发送一个确认报文,然后进入时间等待状态

时间等待状态
进行完步骤5之后TCP还没有完全关闭,而是创建一个时间等待计时器设置的2MSL,MSL是最长报文段寿命,RFC793建议为2分钟,但是对于现在的网络2分钟太长了,可以为更小的值,只有过了2个MSL时间之后,A才会撤销传输控制块TCB,进入TCP关闭状态释放TCP连接 ,而B在收到确认之后就撤销传输控制块TCB,进入TCP关闭状态了,所以B要比A更早进入关闭状态

如果A在2个MSL时间之内又收到B的释放连接报文,那么说明确认报文丢失了,这时将重新进第5步骤。
步骤1,2,4,5称为4次握手,也叫4次挥手

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值