传输层在网络层提供的服务基础上,实现了端对端之间的服务
知识点
- UDP
- TCP
- UDP和TCP如何实现复用和解复用
- TCP如何实现可靠传输、流量控制、拥塞控制
- TCP的连接建立与连接拆除,通俗来说就是三次握手、四次挥手
总的来说,能把TCP和UDP全部理清楚即可
首先先来总体概括一下TCP和UDP
-
传输层主要的两个协议是UDP和TCP
-
UDP:User Datagram protocol,用户数据报协议,无连接服务
-
TCP:Transmission Control Protocol,传输控制协议,面向连接服务
-
传输层的连接是指:两个应用进程在进行通信前,需不需要进行连接,连接可以确保通信的正常进行
多路复用与解复用
-
这里的多路复用是指:应用层复用的是同一层的UDP和TCP实体,也就是多个应用会使用同一个UDP和TCP实体来进行发送分组
-
这里的解复用是指:当TCP和UDP实体收到了网络层传递的分组时,可以准确分配到各个应用进程
-
这里首先要理解,应用层都是通过Socket套接字来调用传输层服务的,一个应用进程可以有多个Socket,也就形成了一对多,当然TCP、UDP实体只有一个,其也是形成了一对多
-
socket绑定了一些连接信息,TCP和UDP的socket是不一样的,TCP的socket里面有目标IP、目标端口、自身IP、自身端口还有PID(进程ID);而UDP的socket则仅仅只有自身IP、自身端口和PID,这是因为TCP提供的是面向连接的服务,socket会去维护连接的信息,这样做的目的是让与该连接有关联的分组都交由该socket来发送给对方或者返回给上层,而UDP提供的是无连接服务,将每个分组都视为独立,独立去发送、处理每一个分组,不需要记录分组的状态(都是独立的),所以不需要去维护连接信息,直接全部交由对应应用程序处理即可
-
TCP和UDP实体里面都维护了自身的Socket表,当TCP和UDP接收到分组的时候,会对比socket表来进行分派分给应用层的应用程序,TCP主要是根据源IP地址、源端口号、目标IP地址、目标端口号,从而找到对应的socket;而UDP则只需源IP地址、源端口号即可找到对应的socket,使用对应的socket返回给上面的应用程序
-
TCP所谓的连接,其实指的就是对应的socket的连接,比如两个应用进程进行连接通信,整个通信过程都将是对应的两个socket之间,socket都绑定了对方的信息,从而记录了这条端对端连接,以后的通信都是基于该连接进行!对于接收到的属于同个应用程序,但不同连接的分组会分配到对应的scoket进行处理;但是UDP虽然也是基于两个socket进行通信,但却不会绑定对方信息,也不会去记录这条端对端连接,对于接收到的属于同个应用程序,但不同连接的分组都是交由同个socket一致处理
UDP
UDP协议称为User Datagram Protocol,也就是用户数据报,其封装之后的数据称为数据报
UDP的实现比较简单
- UDP仅仅在原来的IP服务的不可靠服务上添加了复用和解复用、差错检测功能,依然提供的是不可靠的服务!
- UDP是无连接的,也就是对于所有分组都视为独立的分组进行处理,不需要在通信前连接建立和通信后拆除连接上占用额外的资源
- UDP是面向报文的,也就是说对于网络层传来的报文,只是简单将头部去除了之后就将数据部分交由应用层了;对于应用层的处理也只是简单添加了头部之后就交由网络层发送了,也就是说UDP会一次交付完整的报文,并不会进行分片、重组等操作,因此选用UDP协议的时候,要考虑应用层的报文长度,太长的话会导致网络层对其进行分片重组,降低了网络层的效率,太小的话又不能充分利用网络层的资源!
- UDP尽最大努力去交付报文,但不会对报文负责,不保证报文一定被接收方接收到了
- UDP支持一对一、一对多以及多对多
- UDP不支持拥塞控制、流量控制、和提供可靠服务,其仅仅支持差错检测
- UDP的首部开销小,仅仅只有8个字节,相比于TCP的20个字节,要占用更少的空间
UDP的报文格式
UDP的报文格式也分为首部和数据部分
-
首部:占用八个字节,可以看到UDP并没有IP地址,因为IP地址是在IP层上应用的!在IP层进行封装和解封装的!解封装之后是会传上来使用的,而传输层使用的则是端口号,关注的是端口号!
- 源端口:源端口号,应用层用来响应的时候会使用到这个字段
- 目的端口:目的端口号
- 长度:UDP报文长度,可以通过此来计算出数据部分
- 校验和:用来检验首部是否出现错误,如果出现错误,报文就代表出错了
-
数据部分:也就是应用层传过来的报文
对于UDP报文的处理细节
- 如果对比UDP实例中的scoket表,发送目的端口号不存在,则会视为端口不可达,发送对应类型的ICMP报文,进行差错报告
对于UDP报文的校验
-
当接收到一个UDP数据报的时候,会利用其校验和进行检验,这里要注意,校验和的形成不仅仅与首部相关,还会与数据部分相关!因此也可以用来检测数据部分是否出现了问题!而IP仅仅只是检验了首部
-
校验和字段初始化方式:12字节的伪首部 + UDP首部 + UDP数据部分,计算方式为,首先把16位全0填充进校验和字段,然后将各个部分拆分成一段段16位字,伪首部占12字节、UDP首部占8字节,肯定可以刚好拆分的,但如果UDP数据部分不是偶数个字节,则会进行填充0,填充到1个字节的0,这些填充0是不会被发送的,同理伪首部也不会发送的!!,每段16位字进行相加之后然后进行反码得到16位的校验和(超出的高位作为低位的进位!)
-
关于伪首部:伪首部虽然不会参与运算,但却是可以计算得出,伪首部的组成有5个部分
- 源IP地址:4个字节
- 目标IP地址:4个字节
- 8位全0+8位协议代码:2个字节,协议代码是UDP或者TCP,如果是UDP则为17(0X11)!
- UDP用户数据报长度:2个字节
-
检验和的使用:当接收方接收到UDP用户数据报时,计算出伪首部,然后伪首部、UDP数据报头部和UDP数据部分同样分成一段段16位字,然后与UDP数据报头部中的校验和字段进行二进制相加,其结果最后为全1,则代表无误,否则代表发生错误了,因为checksum保存的是反码!
-
当checksum校验出错的时候,可能会选择直接抛弃该分组,也可能会将错误信息上交给上层的应用层
-
检错方式虽然能力不强,但处理简单,处理起来快!
TCP
TCP协议全称为Transmisson Controler Protocol,称为传输控制协议
TCP的特点
- 面向连接:两个应用进程在通信前,必须要建立TCP连接,这里的连接也就是上面我们提到的socket连接,绑定了对方的信息!
- 提供可靠的交付服务,通过TCP连接发送的数据,不出现乱序、丢失、重复等问题
- 有拥塞控制和流量控制功能
- 采用全双工的通信,允许发送和接收动作同时发生,具体的实现是,TCP的两端设定了发送缓存和接收缓存,应用层将要发送的数据放在TCP的发送缓存中就可以去做自己的事情了,而TCP会在适当的时机将发送缓存中的数据进行发送;同理,TCP把收到的数据放在接收缓存中,在适当的时机会传给应用层
- 面向字节流,TCP会将缓存中的数据视为一连串的字节形成的无结构的字节流,发送的时候也是以这种字节流的形式发送
TCP的功能,在网络层提供的服务上,还添加了以下功能
- 多路复用、解复用
- 可靠传输
- 拥塞控制
- 流量控制
可靠传输的实现
RDT
IP层仅仅提供最大努力的服务,并不可靠,而TCP为了让其变得可靠,那么就要进行增强处理
因此TCP有三种协议来实现可靠传输
- 停止等待协议(stop-and-waiting)
- 回退N协议(go-back-N)
- 选择重传协议(sr)
不过在认识这三种协议之前,我们必须要认识一下RDT的一个发展过程,RDT其实就是可靠数据传输,并不是一个协议,而是一种概念,就是当依赖的下层是不可靠的时候,上层怎么去提供可靠的服务
网络上的分组传输过程中的两个问题
- 分组出错
- 分组丢失
RDT1.0
前提条件:网络很好,下层接收到的分组没有出错、也没有丢失,RDT1.0直接对分组进行解封装然后传递给上层即可
待解决的问题:啥也没解决,搁着搁哪的
RDT2.0
前提条件:网络差了一点,分组出现出错了,但没有丢失,使用了ACK/NAK确认码来实现了检错重传机制
- 发送方发送分组,并做好分组备份
- 接收方接收到了分组,并去进行校验,如果没问题,发送ACK确认码,如果出错了,发送NAK错误码
- 发送方收到了接收方的响应,如果是ACK确认码,则发送下一个分组;如果收到的是NAK错误码,则进行重传
出现了新的问题,ACK、NAK丢失、出错了怎么办,甚至NAK变成了ACK。。。
RDT3.0
对于RDT2.0的问题进行优化,首先,肯定不能再加多一层对确认码检错的功能!因为这是一个无底洞!!
- 去除了NAK,因为会出现变化问题,因此不需要NAK了,只发送ACK确认码
- 使用编号,给每个分组和ACK带上编号,ACK上的编号代表接收方确认收到了什么分组,比如ACK0,代表0号分组确认接收;可以发送1号分组了,假如发送1号分组,收到了ACK0,代表出错了,只确认了0号分组,并没有确认1号分组,因此需要重发1号分组
- 总的来说就是使用了编号的技术,解决了确认码出现错误的问题,并且解决了重复接收问题,接收方可以通过对比编号来看之前是不是已经收到过该分组
但还有丢失的问题没有解决!
RDT4.0
- 在RDT3.0的基础上,添加了定时重发功能,当发送一个分组就会开启定时器,如果在一定时间内没有接收到确认码则会进行重发
RDT整个发展历程就是这样
停止等待协议
stop-waiting协议,底层的概念其实就是RDT4.0,过程如下
- 发送方发送带有编号的分组,并开启定时器
- 接收方响应带有编号的ACK
- 发送方接收到发送方对应的ACK,根据ACK的编号去发送下一个分组!因此ACK的编号其实代表的含义是接收方想要的分组
- 发送方发送了分组就会进行等待,等待ACK的到来才会发送下一个分组,因此称为停止等待协议
- 当超过了定时器时,就会进行重发分组
- 如果超时了之后,发送方进行重发了,并且收到了迟到的ACK确认,那么也会视为确认,然后发送下一个分组,然后接收方根据重发的分组会进行抛弃,并且再次发送ACK,发送方收到了已经确认过的ACK,直接抛弃!!
要注意的以下几点
- 发送方每发送一个分组前都要做好备份,并且要记录确认的ACK
- 分组和确认的ACK都要进行编号,ACK的编号代表了接收方想要发送方发送的分组
- 定时器的超时时间一般设置成比平均往返时间要长一些
出现的问题
- 每次只发送一个分组,然后等待分组的确认才发送下一个分组,导致信道的利用率会很低,发送方的信号在发送了分组之后就空闲了!
信号利用率计算: T D / ( T D + R T T + T A ) , T D 代 表 发 送 的 分 组 占 用 的 时 间 , 分 母 代 表 往 返 时 间 , R T T 是 路 由

最低0.47元/天 解锁文章
2344

被折叠的 条评论
为什么被折叠?



