UDP与TCP详解

1.UDP

1.1什么是UDP协议

UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在第四层——传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。

1.2UDP的包头

在这里插入图片描述

1.3UDP的特点

  1. 面向无连接
  2. 有单播,多播,广播的功能
  3. UDP是面向报文的
  4. 不可靠性
  5. 头部开销小,传输数据报文时是很高效的。

1.4基于 UDP 的几个例子

  • 直播。直播对实时性的要求比较高,宁可丢包,也不要卡顿的,所以很多直播应用都基于 UDP 实现了自己的视频传输协议
  • 实时游戏。游戏的特点也是实时性比较高,在这种情况下,采用自定义的可靠的 UDP 协议,自定义重传策略,能够把产生的延迟降到最低,减少网络问题对游戏造成的影响
  • 物联网。一方面,物联网领域中断资源少,很可能知识个很小的嵌入式系统,而维护 TCP 协议的代价太大了;另一方面,物联网对实时性的要求也特别高。比如 Google 旗下的 Nest 简历 Thread Group,推出了物联网通信协议 Thread,就是基于 UDP 协议的

2.TCP

2.1什么是TCP协议

TCP协议全称是传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议,由 IETF 的RFC 793定义。TCP 是面向连接的、可靠的流协议。流就是指不间断的数据结构,你可以把它想象成排水管中的水流。

2.2TCP协议的包头

在这里插入图片描述

2.2TCP协议的包头介绍

  • 16位源端口号:16位的源端口中包含初始化通信的端口。源端口和源IP地址的作用是标识报文的返回地址。

  • 16位目的端口号:16位的目的端口域定义传输的目的。这个端口指明报文接收计算机上的应用程序地址接口。

  • 32位序号:32位的序列号由接收端计算机使用,重新分段的报文成最初形式。当SYN出现,序列码实际上是初始序列码(Initial Sequence Number,ISN),而第一个数据字节是ISN+1。这个序列号(序列码)可用来补偿传输中的不一致。

  • 32位确认序号:32位的序列号由接收端计算机使用,重组分段的报文成最初形式。如果设置了ACK控制位,这个值表示一个准备接收的包的序列码。

  • 4位首部长度:4位包括TCP头大小,指示何处数据开始。

  • 保留(6位):6位值域,这些位必须是0。为了将来定义新的用途而保留。

  • 标志:6位标志域。表示为:紧急标志、有意义的应答标志、推、重置连接标志、同步序列号标志、完成发送数据标志。按照顺序排列是:URG、ACK、PSH、RST、SYN、FIN。

  • 16位窗口大小:用来表示想收到的每个TCP数据段的大小。TCP的流量控制由连接的每一端通过声明的窗口大小来提供。窗口大小为字节数,起始于确认序号字段指明的值,这个值是接收端正期望接收的字节。窗口大小是一个16字节字段,因而窗口大小最大为65535字节。

  • 16位校验和:16位TCP头。源机器基于数据内容计算一个数值,收信息机要与源机器数值 结果完全一样,从而证明数据的有效性。检验和覆盖了整个的TCP报文段:这是一个强制性的字段,一定是由发送端计算和存储,并由接收端进行验证的。

  • 16位紧急指针:指向后面是优先数据的字节,在URG标志设置了时才有效。如果URG标志没有被设置,紧急域作为填充。加快处理标示为紧急的数据段。

  • 选项:长度不定,但长度必须为1个字节。如果没有选项就表示这个1字节的域等于0。

  • 数据:该TCP协议包负载的数据。

6位标志位:

  • URG: 紧急指针是否有效
  • ACK: 确认号是否有效
  • PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走
  • RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段
  • SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段
  • FIN: 通知对方, 本端要关闭了, 我们称携带FIN标识的为结束报文段

2.2八大特性

(1)确认应答(保证稳定性的核心特性)
(2)超时重传:
a.为了解决确认应答的非正常情况
b.对于发送发重复消息的问题,不用担心,因为系统(内核)已经过滤掉了这些消息
超时重发策略:
a.以指数那么的形式进行超时重传
b.如果发送一定次数之后,还没有响应,那么就认为对方下线
(3)连接管理机制
连接:3次握手
断开连接:4次挥手

有连接必须有4个能力:
a.发送的发送能力
b.发送的接收能力
c.接收端的发送能力
d接收端的接收能力

注意事项:

1.两次握手不可以
2.四次握手可以,但是没有必要
3.三次挥手有可能可以,这个要看接收端缓冲区有没有任务,如果没有任务,那么三次挥手就可以

(4)滑动窗口
a.数据包已经抵达, ACK被丢了.
这种情况下, 部分ACK丢了并不要紧, 因为可以通过后续的ACK进行确认;
b. 数据包就直接丢了.
(5)流量控制
根据接收缓冲区的实际情况,控制发送的速度。
如果tcp协议头的16位窗口为0,表示接收缓冲区已经满了,不能再发了。此时发送端就不会进行消息发送了,发送端会定时发送一个探测包,用来检测接收缓冲区的大小,如果接收缓冲区有值了,那么消息就可以继续发送了。
(6)拥塞控制
和你当前网络有关
规则:发包从1开始,以默认值16为临界值,当小于此值的时候,以指数增长的方式发包,当等于这个此值就有线性增长的方式发包,一直到右大量丢包的请求()
(7)延迟应答
注意事项:

延迟应答时间不能超过MSL(最大生存周期),如果超过MSL,就会触发超时重传(用来提高消息传输的性能)

(8)捎带应答

2.3TCP三次握手

TCP 的建立连接称为三次握手,可以简单理解为下面这种情况

A:您好,我是 A
B:您好 A,我是 B
A:您好 B

对于 A 来说它发出请求,并收到了 B 的响应,对于 B 来说它响应了 A 的请求,并且也接收到了响应。

TCP 的三次握手除了建立连接外,主要还是为了沟通 TCP 包的序号问题。

A 告诉 B,我发起的包的序号是从哪个号开始的,B 同样也告诉 A,B 发起的 包的序号是从哪个号开始的。

双方建立连接之后需要共同维护一个状态机,在建立连接的过程中,双方的状态变化时序图如下所示
在这里插入图片描述

这是网上经常见到的一张图,刚开始的时候,客户端和服务器都处于 CLOSED 状态,先是服务端主动监听某个端口,处于 LISTEN 状态。然后客户端主动发起连接 SYN,之后处于 SYN-SENT 状态。服务端接收了发起的连接,返回 SYN,并且 ACK ( 确认 ) 客户端的 SYN,之后处于 SYN-SENT 状态。客户端接收到服务端发送的 SYN 和 ACK 之后,发送 ACK 的 ACK,之后就处于 ESTAVLISHED 状态,因为它一发一收成功了。服务端收到 ACK 的 ACK 之后,也处于 ESTABLISHED 状态,因为它也一发一收了。

2.4TCP四次挥手

说完建立连接,再说下断开连接,也被称为四次挥手,可以简单理解如下

A:B 啊,我不想玩了
B:哦,你不想玩了啊,我知道了
这个时候,只是 A 不想玩了,即不再发送数据,但是 B 可能还有未发送完的数据,所以需要等待 B 也主动关闭。
B:A 啊,好吧,我也不玩了,拜拜
A:好的,拜拜

这样整个连接就关闭了,当然上面只是正常的状态,也有些非正常的状态(比如 A 说完不玩了,直接跑路,B 发起的结束得不到 A 的回答,不知道该怎么办或则 B 直接跑路 A 不知道该怎么办),TCP 协议专门设计了几个状态来处理这些非正常状态
在这里插入图片描述

断开的时候,当 A 说不玩了,就进入 FIN_WAIT_1 的状态,B 收到 A 不玩了的消息后,进入 CLOSE_WAIT 的状态。

A 收到 B 说知道了,就进入 FIN_WAIT_2 的状态,如果 B 直接跑路,则 A 永远处与这个状态。TCP 协议里面并没有对这个状态的处理,但 Linux 有,可以调整 tcp_fin_timeout 这个参数,设置一个超时时间。

如果 B 没有跑路,A 接收到 B 的不玩了请求之后,从 FIN_WAIT_2 状态结束,按说 A 可以跑路了,但是如果 B 没有接收到 A 跑路的 ACK 呢,就再也接收不到了,所以这时候 A 需要等待一段时间,因为如果 B 没接收到 A 的 ACK 的话会重新发送给 A,所以 A 的等待时间需要足够长。

1.服务端状态转化:

  • [CLOSED -> LISTEN] 服务器端调用listen后进入LISTEN状态, 等待客户端连接;
  • -[LISTEN -> SYN_RCVD] 一旦监听到连接请求(同步报文段), 就将该连接放入内核等待队列中,
    并向客户端发送SYN确认报文.
  • [SYN_RCVD -> ESTABLISHED] 服务端一旦收到客户端的确认报文, 就进入ESTABLISHED状态,
    可以进行读写数据了.
  • [ESTABLISHED -> CLOSE_WAIT] 当客户端主动关闭连接(调用close), 服务器会收到结束报文
    段, 服务器返回确认报文段并进入CLOSE_WAIT;
  • [CLOSE_WAIT -> LAST_ACK] 进入CLOSE_WAIT后说明服务器准备关闭连接(需要处理完之前
    的数据); 当服务器真正调用close关闭连接时, 会向客户端发送FIN, 此时服务器进入LAST_ACK
    状态, 等待最后一个ACK到来(这个ACK是客户端确认收到了FIN)
  • [LAST_ACK -> CLOSED] 服务器收到了对FIN的ACK, 彻底关闭连接.

2.客户端状态转化:

  • [CLOSED -> SYN_SENT] 客户端调用connect, 发送同步报文段;
  • [SYN_SENT -> ESTABLISHED] connect调用成功, 则进入ESTABLISHED状态, 开始读写数据;
  • [ESTABLISHED -> FIN_WAIT_1] 客户端主动调用close时, 向服务器发送结束报文段, 同时进入
    FIN_WAIT_1;
  • [FIN_WAIT_1 -> FIN_WAIT_2] 客户端收到服务器对结束报文段的确认, 则进入FIN_WAIT_2, 开
    始等待服务器的结束报文段;
  • [FIN_WAIT_2 -> TIME_WAIT] 客户端收到服务器发来的结束报文段, 进入TIME_WAIT, 并发出
    LAST_ACK;
  • [TIME_WAIT -> CLOSED] 客户端要等待一个2MSL(Max Segment Life, 报文最大生存时间)的
    时间, 才会进入CLOSED状态.

3.UDP与TCP比较

1.对比
在这里插入图片描述
2. 总结

  • TCP向上层提供面向连接的可靠服务 ,UDP向上层提供无连接不可靠服务。
  • 虽然 UDP 并没有 TCP 传输来的准确,但是也能在很多实时性要求高的地方有所作为
  • 对数据准确性要求高,速度可以相对较慢的,可以选用TCP
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值