TCP/UDP

376 阅读10分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情

UDP

UDP(User Datagram Protocol: 用户数据报协议),是一个非常简单的协议

preview

特点

UDP协议的特点:

  • UDP是无连接协议;
  • UDP不能保证可靠的交付数据; (即不可靠传输)
  • UDP是面向报文传输的;
  • UDP没有拥塞控制;
  • UDP首部开销很小。

TCP

TCP(Transmission Control Protocol: 传输控制协议),是计算机网络中非常复杂的一个协议。

preview

特点

TCP协议的特点:

  • TCP是面向连接的协议;
  • TCP是面向字节流的协议;
  • TCP的一个连接有两端,即点对点通信;
  • TCP提供可靠的传输服务;
  • TCP协议提供全双工通信(每条TCP连接只能一对一)

功能

TCP协议的功能:

  1. 对应用层报文进行分段和重组;
  2. 面向应用层实现复用与分解;
  3. 实现端到端的流量控制;
  4. 拥塞控制;
  5. 传输层寻址;
  6. 对收到的报文进行差错检测(首部和数据部分都检错);
  7. 实现进程间的端到端可靠数据传输控制。

三次握手

preview

为什么需要三次握手?

  1. 第一次握手:客户发送请求,此时服务器知道客户能发;
  2. 第二次握手:服务器发送确认,此时客户知道服务器能发能收;
  3. 第三次握手:客户发送确认,此时服务器知道客户能收。

详细过程

第一次:客户向服务器发送连接请求段,建立连接请求控制段(SYN=1),表示传输的报文段的第一个数据字节的序列号是x,此序列号代表整个报文段的序号(seq=x);客户端进入 SYN_SEND (同步发送状态);

第二次:服务器发回确认报文段,同意建立新连接的确认段(SYN=1),确认序号字段有效(ACK=1),服务器告诉客户端报文段序号是y(seq=y),表示服务器已经收到客户端序号为x的报文段,准备接受客户端序列号为x+1的报文段(ack_seq=x+1);服务器由LISTEN进入SYN_RCVD (同步收到状态);

第三次:客户对服务器的同一连接进行确认.确认序号字段有效(ACK=1),客户此次的报文段的序列号是x+1(seq=x+1),客户期望接受服务器序列号为y+1的报文段(ack_seq=y+1);当客户发送ack时,客户端进入ESTABLISHED 状态;当服务收到客户发送的ack后,也进入ESTABLISHED状态;第三次握手可携带数据;

四次挥手

preview

为什么要四次挥手?

CLOSE-WAIT

客户端发送了 FIN 连接释放报文之后,服务器收到了这个报文,就进入了 CLOSE-WAIT 状态。这个状态是为了让服务器端发送还未传送完毕的数据,传送完毕之后,服务器会发送 FIN 连接释放报文。

TIME-WAIT

客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。

为什么A在TIME-WAIT状态必须等待2MSL的时间呢?

这么做有两个理由:

  • 为了保证A发送的最后一个ACK报文段能够到达B。 A发送的这个ACK报文段有可能丢失,如果 B 没收到 A 发送来的确认报文,那么A就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。
  • 防止“已经失效的连接请求报文段”出现在本链接中。 A在发送完最后一个ACK报文段后,再经过时间2MSL,就可以使本连接的时间内所产生的所有报文段都从网络中消失。这样下一个新的连接中就不会出现这种旧的连接请求报文段。

假设客户端不等待2MSL,而是在发送完ACK之后直接释放关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭连接状态。

详细过程

第一次:客户向服务器发送释放连接报文段,发送端数据发送完毕,请求释放连接(FIN=1),传输的第一个数据字节的序号是x(seq=x);客户端状态由ESTABLISHED进入FIN_WAIT_1(终止等待1状态)

第二次服务器向客户发送确认段,确认字号段有效(ACK=1),服务器传输的数据序号是y(seq=y),服务器期望接收客户数据序号为x+1(ack_seq=x+1);服务器状态由ESTABLISHED进入CLOSE_WAIT(关闭等待)客户端收到ACK段后,由FIN_WAIT_1进入FIN_WAIT_2;

第三次:服务器向客户发送释放连接报文段,请求释放连接(FIN=1),确认字号段有效(ACK=1),表示服务器期望接收客户数据序号为x+1(ack_seq=x+1);表示自己传输的第一个字节序号是y+1(seq=y+1);服务器状态由CLOSE_WAIT 进入 LAST_ACK (最后确认状态)

第四次客户向服务器发送确认段,确认字号段有效(ACK=1),表示客户传输的数据序号是x+1(seq=x+1),表示客户期望接收服务器数据序号为y+1+1(ack_seq=y+1+1);客户端状态由FIN_WAIT_2进入TIME_WAIT等待2MSL时间,进入CLOSED状态服务器在收到最后一次ACK后,由LAST_ACK进入CLOSED

为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?

这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的连接请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了, 所以你可能未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

不可靠传输带来的问题

不可靠传输信道在数据传输中可能发生的情况:比特差错、乱序、重传、丢失

TCP怎么保证可靠性?简述TCP建立连接和断开连接的过程?

  1. 序列号,确认应答,超时重传

    数据到达接收方,接收方需要发出一个确认应答,表示已经收到该数据段,并且确认序号会说明了它下一次需要接收的数据序列号。如果发送方迟迟未收到确认应答,那么可能是发送的数据丢失,也可能是确认应答丢失,这时发送方在等待一定时间后会进行重传。这个时间一般是2*RTT(报文段往返时间)+一个偏差值

  2. 校验和

    TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段

  3. 拥塞控制

    人如果把拥塞窗口cwnd定的很大,那么发送端不停的发送数据,有可能导致网络拥塞。一般会有慢启动拥塞避免快速重传策略。

慢启动:定义拥塞窗口,一开始设为1,之后每次收到一个确认应答(经过一个RTT),窗口大小乘2.

拥塞避免:设置慢启动阈值,一般开始都为65536。拥塞避免指当前拥塞窗口大小达到这个阈值,拥塞窗口的值不再指数上升,而是加法增加,(每次确认应答/每个RTT,拥塞窗口+1),以避免拥塞。

报文超时处理:包括快速重传快速恢复两种。报文超时重传看作一次拥塞,一旦发生超时重传,窗口阈值变为原来大小的一半,并且将窗口大小设为初始值1,然后进入慢启动过程。

快速重传

在 TCP 传输过程中,如果发生了丢包,接收端就会发送之前重复 ACK,比如 第 5 个包丢了,6、7 达到,然后接收端会为 5,6,7 都发送第四个包的 ACK,这个时候发送端受到了 3 个重复的 ACK,意识到丢包了,就会马上进行重传,而不用等到 RTO (超时重传的时间)

*选择性重传:报文首部可选性中加入 SACK 属性,通过 left edge 和 right edge 标志那些包到了,然后重传没到的包

快速恢复

发送方连续收到了三次重复ACK时,就认为当前网络处于拥塞状态,就会进入快速恢复:

  • 拥塞阈值降低为拥塞窗口一半
  • 拥塞窗口的大小变为拥塞阈值
  • 接着拥塞窗口再线性增加,以适应网络环境;

可靠传输的工作原理

TCP发送的报文段是交给 IP 层传送的,但IP层只能提供尽最大努力服务,那么TCP 下面的网络提供的是不可靠的传输,因此,TCP必须采用适当的措施才能使两个运输层之间的通信变得可靠。

理想的传输条件

  • 传输信道不产生差错
  • 不管发送方以多快的速度发送数据,接收方总是来得及处理收到的数据

使用可靠传输协议达到上述条件,使不可靠的传输信道变为可靠传输信道

基于不可靠信道实现可靠数据传输采取的措施:

  • 差错检测:利用编码实现数据包传输过程中的比特差错检测
  • 确认:接收方向发送方反馈接收状态
  • 重传:发送方重新发送接收方没有正确接收的数据
  • 序号:确保数据按序提交
  • 计时器:解决数据丢失问题;

1️⃣停止等待协议:是最简单的可靠传输协议,但是该协议对信道的利用率不高。

2️⃣连续ARQ(Automatic Repeat reQuest:自动重传请求)协议:滑动窗口+累计确认,大幅提高了信道的利用率。

TCP协议的可靠传输实现

基于连续ARQ协议,但在某些情况下,重传的效率并不高,会重复传输部分已经成功接收的字节。

TCP协议的流量控制

流量控制:让发送方发送速率不要太快,TCP协议使用滑动窗口实现流量控制。

preview

TCP协议的拥塞控制

拥塞控制与流量控制的区别:流量控制考虑点对点的通信量的控制,而拥塞控制考虑整个网络,是全局性的考虑。拥塞控制的方法:慢启动算法+拥塞避免算法。

慢开始和拥塞避免:

  1. 【慢开始】拥塞窗口从1指数增长;
  2. 到达阈值时进入【拥塞避免】,变成+1增长;
  3. 【超时】,阈值变为当前cwnd的一半(不能<2);
  4. 再从【慢开始】,拥塞窗口从1指数增长。

preview

快重传和快恢复:

  1. 发送方连续收到3个冗余ACK,执行【快重传】,不必等计时器超时;
  2. 执行【快恢复】,阈值变为当前cwnd的一半(不能<2),并从此新的ssthresh点进入【拥塞避免】。

preview

TCP与UDP区别

  1. TCP是面向连接的协议,发送数据前要先建立连接,TCP提供可靠的服务,也就是说,通过TCP连接传输的数据不会丢失,没有重复,并且按顺序到达;
  2. UDP是无连接的协议,发送数据前不需要建立连接,是没有可靠性;
  3. TCP通信类似于于要打个电话,接通了,确认身份后,才开始进行通行;
  4. UDP通信类似于学校广播,靠着广播播报直接进行通信。
  5. TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多;
  6. TCP是面向字节流的,UDP是面向报文的; 面向字节流是指发送数据时以字节为单位,一个数据包可以拆分成若干组进行发送,而UDP一个报文只能一次发完。
  7. TCP首部开销(20字节)比UDP首部开销(8字节)要大
  8. UDP 的主机不需要维持复杂的连接状态表

TCP和UDP各自适用的场景

两者都是传输层协议。

  • TCP是可靠的有连接的(收发双方必须建立连接才能传输,三次握手),而UDP是面向无连接的
  • TCP是点对点传输,而UDP可以一对多多对多多对一的交互通信;
  • 可靠性:TCP是无差错,不丢失,不重复,按序到达;UDP是尽最大努力交付;
  • 拥塞控制,流量控制:TCP有拥塞控制和流量控制机制;UDP没有。
  • 首部开销:
    • TCP为20个字节
    • UDP为8个字节(源端口,目的端口,数据长度,校验和)
  • 适用场景: tcp适用于可靠性高的场景,而udp适用于实时性强的场景(即时通信,视频聊天)

对某些实时性要求比较高的情况使用UDP,比如游戏,媒体通信,实时直播,即使出现传输错误也可以容忍;其它大部分情况下,HTTP都是用TCP,因为要求传输的内容可靠,不出现丢失的情况

preview

资料来源

项目与面试

\