TCP/UDP

简介

【Tcp和Udp的介绍以及它们的区别】

介绍:

TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,完成第四层传输层所指定的功能。

UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。UDP在IP报文的协议号是17。

区别:

  1. 基于连接与无连接。
  2. TCP要求系统资源较多,UDP较少。
  3. UDP程序结构较简单。
  4. 流模式(TCP)与数据报模式(UDP)。
  5. TCP保证数据正确性,UDP可能丢包。
  6. TCP保证数据顺序,UDP不保证。
  7. TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接。
  8. TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付。
  9. TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的,UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)。
  10. 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信。
  11. TCP首部开销20字节;UDP的首部开销小,只有8个字节。
  12. TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道。

TCP

【TCP三次握手和四次挥手的过程】

名词解释:

  • TCP(Transmission Control Protocol)传输控制协议

TCP是主机对主机层传输控制协议,为提供可靠的连接服务,采用三次握手来确认建立一个连接。 采用四次挥手来进行协议的终止。

  • 位码 TCP标志位,有以下6种标示:
标志位 英文 含义
SYN synchronouse 建立连接
ACK acknowledgement 确认标志
PSH push 传送标志
FIN finish 结束标志
RST reset 重置标志
URG urgent 紧急标志
  • Sequence number 顺序号码

  • Acknowledgement 确认号码

  • 连接状态

    状态 介绍
    LISTENING 提供某种服务,侦听远方TCP端口的连接请求,当提供的服务没有被连接时,处于LISTENING状态,端口是开放的,等待被连接。
    SYN_SENT (客户端状态) 客户端调用connect,发送一个SYN请求建立一个连接,在发送连接请求后等待匹配的连接请求,此时状态为SYN_SENT。
    SYN_RCVD (服务端状态) 在收到和发送一个连接请求后,等待对方对连接请求的确认,当服务器收到客户端发送的同步信号时,将标志位ACK和SYN置1发送给客户端,此时服务器端处于SYN_RCVD状态,如果连接成功了就变为ESTABLISHED,正常情况下SYN_RCVD状态非常短暂。
    ESTABLISHED ESTABLISHED状态是表示两台机器正在传输数据。
    FIN-WAIT-1 等待TCP连接中断请求的确认,主动关闭端应用程序调用close,TCP发出FIN请求主动关闭连接,之后进入FIN_WAIT1状态。
    FIN-WAIT-2 1、主动关闭端接到FIN ack后,便进入FIN-WAIT-2,这是在关闭连接时,客户端和服务器两次挥手之后的半关闭状态,在这个状态下,客户端应用程序还有接受数据的能力,但是已经无法发送数据;2、另一种情况是主动关闭端收到了服务端的FIN请求
    CLOSE-WAIT 等待从本地用户发来的连接中断请求 ,被动关闭端TCP接到FIN后,就发出ACK以回应FIN请求(它的接收也作为文件结束符传递给上层应用程序),并进入CLOSE_WAIT
    CLOSING 等待远程TCP对连接中断的确认,处于此种状态比较少见
    LAST-ACK 等待原来的发向远程TCP的连接中断请求的确认,被动关闭端一段时间后,接收到文件结束符的应用程序将调用CLOSE关闭连接,TCP也发送一个 FIN,等待对方的ACK.进入LAST-ACK。
    TIME-WAIT 在主动关闭端接收到FIN后,TCP就发送ACK包,并进入TIME-WAIT状态,等待足够的时间以确保远程TCP接收到连接中断请求的确认,很大程度上保证了双方都可以正常结束。
    CLOSED 被动关闭端在接受到ACK包后,就进入了closed的状态,连接结束,没有任何连接状态。

三次握手:

TCP-三次握手

  • 第一次握手:

    Client端发送位码为SYN=1,随机产生seq number=J的数据包到服务器,Server端收到数据包后,由SYN=1判断出 Client端要求连接;此时Client端处于SYN_SENT的状态。

  • 第二次握手:

    Server端收到请求后要向Client端发送确认连接的信息,于是,Server端向Client端发送一个ACK=1,SYN=1,ack number=J+1(即Client端的seq number +1),随机生成的seq number=K,此时服务端处于SYN_RCVD;

  • 第三次握手: Client端收到后检查两点 :

    1、ack number 是否正确(是否等于J+1);

    2、位码ACK是否等于1。

    若以上两点都正确,Client端会再次发送ack num=K+1(第二次机握手中 Server端发送的seq number + 1),位码ACK=1,

    Server端收到后确认ack number值是否正确,ACK是否为1 ,若均正确则连接建立成功。

    此时双方处于ESTABLISHED的状态。

四次挥手:

TCP-四次挥手

  • 第一次挥手:

    Client端发送位码为FIN=1,随机产生seq number=J的数据包到服务器,Server端收到数据包后,由FIN=1判断出 Client端要求断开连接;此时Client端处于FIN-WAIT-1的状态。

  • 第二次挥手:

    Server端收到请求后要向Client端发送确认断开连接的信息,于是,Server端向Client端发送一个ACK=1,ack number=J+1(即Client端的seq number +1),此时服务端处于CLOSE_WAIT的状态,Client端收到这个信号后,由FIN-WAIT-1变成FIN-WAIT-2的状态,此时Client端可以接受Server端的数据但是不能向Server端传输数据。

  • 第三次挥手:

    Server端主动向Client端发送一个位码为FIN=1,随机产生seq number=K 的数据包到服务器,Client端收到数据包后,由FIN=1判断出Server端要断开连接,此时Server端处于LAST-ACK的状态。

  • 第四次挥手:

    Client端接受到Server端的请求后,要向Server端发送确认端口连接的信息,于是,Client端向Server端发送了一个ACK=1,ack num=K+1(即Server端的seq number +1),发送后Client端处于TIME-WAIT的状态,等待2MSL后变成CLOSED,而Server端收到Client端的最后一个ACK后便会变成CLOSED

【为什么要三次握手? 二次握手有什么问题 ?三次握手有哪些缺陷】

  • 为什么三次握手

    谢希仁版《计算机网络》中的例子:

    “已失效的连接请求报文段”的产生

    在这样一种情况下:

    client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。

    本来这是一个早已失效的报文段,但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。

    于是就向client发出确认报文段,同意建立连接。

  • 二次握手有什么问题

    假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。

    由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据,但server却以为新的运输连接已经建立,并一直等待client发来数据。

    这样,server的很多资源就白白浪费掉了。

  • 三次握手有哪些缺陷

    SYN- Flood攻击是当前网络上最为常见的DDoS攻击,也是最为经典的拒绝服务攻击,它就是利用了TCP协议实现上的一个缺陷,通过向网络服务所在端口发送大量 的伪造源地址的攻击报文,就可能造成目标服务器中的半开连接队列被占满,从而阻止其他合法用户进行访问。

    原理:攻击者首先伪造地址对 服务器发起SYN请求,服务器回应(SYN+ACK)包,而真实的IP会认为,我没有发送请求,不作回应。服务器没有收到回应,这样的话,服务器不知道(SYN+ACK)是否发送成功,默认情况下会重试5次(tcp_syn_retries)。这样的话,对于服务器的内存,带宽都有很大的消耗。攻击者 如果处于公网,可以伪造IP的话,对于服务器就很难根据IP来判断攻击者,给防护带来很大的困难。

    解决方法:

    • 无效连接监视释放

      这种方法不停的监视系统中半开连接和不活动连接,当达到一定阈值时拆除这些连接,释放系统资源。这种绝对公平的方法往往也会将正常的连接的请求也会被释放掉,”伤敌一千,自损八百“

    • 延缓TCB分配方法

      SYN Flood关键是利用了,SYN数据报文一到,系统立即分配TCB资源,从而占用了系统资 源,因此有俩种技术来解决这一问题

    • Syn Cache技术

    这种技术在收到SYN时不急着去分配TCB,而是先回应一个ACK报文,并在一个专用的HASH表中(Cache)中保存这种半开连接,直到收到正确的ACK报文再去分配TCB

    • Syn Cookie技术

      Syn Cookie技术则完全不使用任何存储资源,它使用一种特殊的算法生成Sequence Number,这种算法考虑到了对方的IP、端口、己方IP、端口的固定信息,以及对方无法知道而己方比较固定的一些信息,如MSS、时间等,在收到对方 的ACK报文后,重新计算一遍,看其是否与对方回应报文中的(Sequence Number-1)相同,从而决定是否分配TCB资源。

    • 使用SYN Proxy防火墙

【四次挥手TIME_WAIT】

在主动关闭端接收到FIN后,TCP就发送ACK包,并进入TIME-WAIT状态,等待足够的时间以确保远程TCP接收到连接中断请求的确认,很大程度上保证了双方都可以正常结束。

  • 【为什么要等TIME_WAIT】

    TIME_WAIT就是为了防止在连接上有多个重传的FIN包出现,所以必须TIME_WAIT这个是为了防止当再一次建 立相同的新连接时防止收到老连接的数据包从而导致的影响。

  • 【TIME_WAIT为多少】

    2MSL

  • 【TIME_WAIT状态产生的原因是什么】

    • 可靠地实现TCP全双工连接的终止
    • 允许老的报文在网络中消逝
  • 【TIME_WAIT状态处在哪一方】

    先发FIN标志位的一端就会进入TIME_WAIT状态,即不仅仅存在客户端、服务都也会存在

  • 【TIME_WAIT有什么危害】

    高并发短连接的TCP服务器上,当服务器处理完请求后立刻主动正常关闭连接。这个场景下会出现大量socket处于TIME_WAIT状态。如果客户端的并发量持续很高,此时部分客户端就会显示连接不上。

    为什么我们要关注这个高并发短连接呢?有两个方面需要注意:

    1. 高并发可以让服务器在短时间范围内同时占用大量端口,而端口有个0~65535的范围,并不是很多,刨除系统和其他服务要用的,剩下的就更少了。
    2. 在这个场景中,短连接表示“业务处理+传输数据的时间 远远小于 TIMEWAIT超时的时间”的连接。

    TCP处于TIMEWAIT状态时,别的请求过来后,没有空闲的端口可供tcp连接,大大影响服务器响应请求。 长连接业务的服务就不需要考虑TIMEWAIT状态。同时,假如你对服务器业务场景非常熟悉,你会发现,在实际业务场景中,一般长连接对应的业务的并发量并不会很高。

  • 【可以如何避免】

    首先服务器可以设置SO_REUSEADDR套接字(so_reuseaddr)选项来通知内核,如果端口忙,但TCP连接位于TIME_WAIT状态时可以重用端口。在一个非常有用的场景就是,如果你的服务器程序停止后想立即重启,而新的套接字依旧希望使用同一端口,此时SO_REUSEADDR选项就可以避免TIME_WAIT状态。

【流量控制和拥塞控制】

  • 流量控制

    所谓的流量控制就是让发送方的发送速率不要太快,让接收方来得及接受。

    利用滑动窗口机制可以很方便的在TCP连接上实现对发送方的流量控制。

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

  • 拥塞控制

    • 拥塞控制的原理

      在某段时间,若对网络中的某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变化,这种情况叫做拥塞。网络拥塞往往是由许多因素引起的,简单的提高节点处理机的速度或者扩大结点缓存的存储空间并不能解决拥塞问题。拥塞问题的是指往往是整个系统的各个部分不匹配,只有各个部分平衡了,问题才会得到解决。

    • 拥塞控制和流量控制的差别

      概念:所谓拥塞控制就是防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。

      区别:拥塞控制所要做的都有一个前提,就是网络能承受现有的网络负荷。拥塞问题是一个全局性的问题,涉及到所有的主机、所有的路由器、以及与降低网络传输性能有关的所有因素。

      流量控制往往指的是点对点通信量的控制,是个端到端的问题。流量控制所要做的就是控制发送端发送数据的速率,以便使接收端来得及接受。

    • 拥塞控制方法

      因特网建议标准RFC2581定义了进行拥塞控制的四种算法,即慢开始(Slow-start)、拥塞避免(Congestion Avoidance)、快重传(Fast Restrangsmit)和快回复(Fast Recovery)

【TCP如何保证可靠传输】

  • 校验和

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

  • 序列号与确认应答

    序列号:TCP传输时将每个字节的数据都进行了编号,这就是序列号。

    确认应答:TCP传输的过程中,每次接收方收到数据后,都会对传输方进行确认应答。也就是发送ACK报文。这个ACK报文当中带有对应的确认序列号,告诉发送方,接收到了哪些数据,下一次的数据从哪里发。序列号的作用不仅仅是应答的作用,序列号能够将接收到的数据根据序列号排序,并且去掉重复序列号的数据。这也是TCP传输可靠性的保证之一。

  • 超时重传

    在进行TCP传输时,由于确认应答和序列号机制,发送端在发送一部分数据后,会等待接收端发送的ACK报文。但由于网络原因:

    1. 数据在发送过程中发生了丢包,接收端没有接收到。

    2. 接收端接收到数据后,发送了ACK报文,但ACK报文发生了丢包,发送端没有接收到。

    TCP使用超时重传机制来解决问题,发送端在发送数据之后,会等待一段时间,如果时间到达后,还没收到ACK报文,则重新发送刚才的数据。接收端在接收到重发的数据,会从序列号中确认数据是否已经接收过,如果没有接收过,则接收数据,并返回ACK报文;如果已经接收过,则直接抛弃,返回ACK报文。

  • 流量控制

    TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)

  • 拥塞控制

    当网络拥塞时,减少数据的发送。

  • 停止等待协议

    也是为了实现可靠传输的,它的基本原理就是每发完一个分组就- 停止发送,等待对方确认。在收到确认后再发下一个分组。 超时重传: 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。

【发送方发送频率过高造成丢包,TCP是如何解决的】

TCP协议本身确保传输的数据不会丢失完整性。如果在传输过程中发现数据丢失或数据包丢失,最大的可能性是在发送或接收程序的过程中出现问题。

解决方案包括拆包、添加包头和发送组合包。如果服务器或客户端断开连接,一般会使用心跳测试。

心跳测试:每隔一段时间向服务器发送数据包。为了节省资源,通常会发送空数据包。如果发送失败表明套接字已断开,此时需要根据特定条件释放资源并重新连接。

【数据中心网络下TCP的缺陷不足】

简介:当网络发生拥塞的时候,会严重影响TCP的吞吐量,这个问题在数据中心网络上表现更加严重。

UDP

【UDP不可靠会丢包,为什么还用它】

UDP它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。

【如何实现UDP的可靠传输】

简介:

UDP是User Datagram Protocol,一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。可靠性由上层应用实现,所以要实现udp可靠性传输,必须通过应用层来实现和控制

如何实现:

传输层无法保证数据的可靠传输,只能通过应用层来实现了。实现的方式可以参照tcp可靠性传输的方式,只是实现不在传输层,实现转移到了应用层。实现以下几点:

  • 确认机制
  • 重传机制
  • 滑动窗口

目前有如下开源程序利用udp实现了可靠的数据传输。分别为RUDP、RTP、UDT。

  • RUDP

    RUDP 提供一组数据服务质量增强机制,如拥塞控制的改进、重发机制及淡化服务器算法等,从而在包丢失和网络拥塞的情况下, RTP 客户机(实时位置)面前呈现的就是一个高质量的 RTP 流。在不干扰协议的实时特性的同时,可靠 UDP 的拥塞控制机制允许 TCP 方式下的流控制行为。

  • RTP

    实时传输协议(RTP)为数据提供了具有实时特征的端对端传送服务,如在组播或单播网络服务下的交互式视频音频或模拟数据。应用程序通常在 UDP 上运行 RTP 以便使用其多路结点和校验服务;这两种协议都提供了传输层协议的功能。但是 RTP 可以与其它适合的底层网络或传输协议一起使用。如果底层网络提供组播方式,那么 RTP 可以使用该组播表传输数据到多个目的地。

    RTP 本身并没有提供按时发送机制或其它服务质量(QoS)保证,它依赖于底层服务去实现这一过程。 RTP 并不保证传送或防止无序传送,也不确定底层网络的可靠性。 RTP 实行有序传送, RTP 中的序列号允许接收方重组发送方的包序列,同时序列号也能用于决定适当的包位置,例如:在视频解码中,就不需要顺序解码。

  • UDT

    基于UDP的数据传输协议(UDP-basedData Transfer Protocol,简称UDT)是一种互联网数据传输协议。UDT的主要目的是支持高速广域网上的海量数据传输,而互联网上的标准数据传输协议TCP在高带宽长距离网络上性能很差。顾名思义,UDT建于UDP之上,并引入新的拥塞控制和数据可靠性控制机制。UDT是面向连接的双向的应用层协议。它同时支持可靠的数据流传输和部分可靠的数据报传输。由于UDT完全在UDP上实现,它也可以应用在除了高速数据传输之外的其它应用领域,例如点到点技术(P2P),防火墙穿透,多媒体数据传输等等。