TPC和UDP协议

OSI七层模型和TCP/IP四层模型

  • 应用层
  • 表示层
  • 会话层
  • 传输层
  • 网络层
  • 数据链路层
  • 物理层

TCP/IP 四层概念:

  • 应用层:应用层、表示层、会话层:HTTP
  • 传输层:传输层:TCP/UDP
  • 网络层:网络层:IP
  • 数据链路层:数据链路层、物理层

什么是TCP

TCP协议简单来说是一种位于传输层的,面向连接的、可靠的、基于字节流的传输层通信协议

TCP的特点

  • TCP是面向连接的传输层协议。比如说TCP的三次握手,四次分手,针对的都是连接。而 UDP 没有相应建立连接的过程,只是一直在发送数据。
  • 每一条TCP连接只能有两个端点,每一条TCP连接是点对点的。也就是说TCP是不同计算机之间的进程的通信
  • TCP提供可靠交付的服务,无差错,不丢失,不重复,按序到达。总结一下就是,可靠有序,不丢不重
  • TCP提供全双工通信。全双工指的是连接双方可以同时收发数据。在收发两端都有发送缓存和接收缓存,发送缓存就是一个准备发送的队列,接收缓存是一个准备接收的队列。
  • 有状态,TCP 会精准记录哪些数据发送了,哪些数据被对方接收了,哪些没有被接收到,而且保证数据包按序到达,不允许半点差错。这是有状态
  • 可控制,当意识到丢包了或者网络环境不佳,TCP 会根据具体情况调整自己的行为,控制自己的发送速度或者重发。这是可控制

什么是UDP

UDP协议是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。

UDP的特点

  • UDP是无连接的,减少开销和发送数据之前的时间延迟。大家都知道TCP三次握手和四次分手,这个是需要时间花销的,但是UDP没有这部分花销。

  • UDP使用最大努力交付,即不保证可靠交付。那谁来保证可靠的交付呢?是由UDP的上一层协议,应用层来保证。

  • UDP是面向报文的,适合一次性传输少量数据的网络应用。什么意思呢,如下图,UDP这层,把应用层的全部内容作为自己的数据报部分,在IP层也只是加了一个IP首部,我们知道,在以太网,链路层上的数据如果超过1500字节,就会分片,所以网络层发现上面传输层给了太大的数据就会分片,加上UDP是不可靠的协议,这就加大了UDP的不可靠性,容易丢失,所以UDP适合数据量少的。
    图片说明

  • UDP没有拥塞控制,适合很多实时应用。也就是说如果网络堵塞,UDP不管那么多,照样按照自己的速率发数据,那有些人就会说,这协议是不是有点坑B,路都堵上了,还发死劲发数据呢,但是反过来看,这也是UDP的优点,它允许丢包,如果你的网络情况还不错,UDP就非常适合实时应用,比如视频会议。

    UDP首部较小,只有8字节,而TCP由有·0字节。这也是减少网络传输开销的一方面。

TCP的三次握手

TCP 的三次握手,是为了需要确认双方的两样能力: 发送的能力接收的能力

tpc的报文中,有6个控制位:

控制位 作用
ACK 置1时表示确认号合法,为0的时候表示数据段不包含确认信息,确认号被忽略
PSH 置1时请求的数据段在接收方得到后就可直接送到应用程序,而不必等到缓冲区满时才传送
RST 置1时重建连接。如果接收到RST位时候,通常发生了某些错
SYN 置1时用来发起一个连接
FIN 置1时表示发端完成发送任务。用来释放连接,表明发送方已经没有数据发送了
URG 紧急指针,告诉接收TCP模块紧要指针域指着紧要数据

图片说明

第一步:发送方发送一个数据包给接收方,接收方确认发送方的发送能力

客户端要发送一个数据包告诉服务器要建立连接,根据上面我们了解到的控制位信息,建立连接需要把SYN置为1seq指的是序号,是随机产生的。

第二步:接收方返回一个确认报文给发送方,发送方确认接收方的发送和接收能力

服务器收到该数据包后,会为该TCP连接分配缓存和变量,缓存指的是一个字节流队列。(发送方和接收方都有这个队列,而且如果双方需要互相通信,那么双方都会有发送缓存和接收缓存),接着会返回一个确认报文,其中SYN控制位置为1,意思是允许建立连接,ACK是确认号,确认收到了发送方的包,并且会设一个seq序号,也为一个随机数。小写ack是确认号,也就是接下来希望发送方要发的数据从发送方发送到的seq序号+1开始。

第三步:发送方发送确认给接收方,接收方确认了发送方的接收能力

客户端需要给服务器端返回一个确认,此时SYN控制位变为0,意思这不是建立连接的请求了,要正式发数据了,ACK是确认码,意思是收到了服务器的确认请求了。小写ack是确认号,也就是接下来希望接收方要发的数据从接收方返回的seq序号+1开始。

TCP的四次挥手

图片说明

第一步:客户端发起请求,请求断开链接。FIN=1,seq=u。u是之前传送过来的最后一个字节的序号+1

第二步:服务器收到客户端的请求断开链接的报文之后,返回确认信息。ACK=1,seq=v,ack=u+1。这个时候,客户端不能给服务器发送信息报文,只能接收。但是服务器要是还有信息要传给服务器,仍然能传送。这里的v是什么意思呢,这就取决于服务器发送给客户端之前的一个包确认号是多少了。

第三步:当服务器也没有了可以传的信息之后,给客户端发送请求结束的报文。FIN=1,ACK=1,ack=u+1,seq=w。这里的w,跟上面的v是一个意思,为什么不都是v呢,因为这一步和上一步中间可能还在发数据呢,所以seq这个数据发送的字节流序号可能要变。

第四步:客户端接收到FIN=1的报文之后,返回确认报文,ACK=1,seq=u+1,ack=w+1。发送完毕之后,客户端进入等待状态,等待两个时间周期。关闭

常见问题

三次握手

为什么不能用两次握手进行连接?

无法确认客户端的接收能力。

可能造成的问题:

  1. 若建立连接只需两次握手,客户端并没有太大的变化,仍然需要获得服务端的应答后才进入ESTABLISHED状态,而服务端在收到任意连接请求后就进入ESTABLISHED状态。

    如果此时网络拥堵,客户端收到的发送请求迟迟到不了服务端,客户端便超时重发请求,双方便开始通信,通信结束后释放连接。此时如果之前那个迟迟到不了服务端,滞留在网路中的请求到达了服务端,由于只有两次握手,服务端收到请求就会进入ESTABLISHED状态,等待发送数据或主动发送数据。但这时客户端已经关闭,服务端就会一直等待下去,浪费服务端连接资源。

  2. 在第二次握手时,服务器对客户端发送的序列号做了确认,第三次握手时,客户端对服务器的序列号做确认,如果没有第三次握手,则不能保证传输的可靠性。

三次握手过程中可以携带数据吗?

第三次握手的时候,可以携带。前两次握手不能携带数据。

如果前两次握手能够携带数据,那么一旦有人想攻击服务器,那么他只需要在第一次握手中的 SYN 报文中放大量数据,那么服务器势必会消耗更多的时间内存空间去处理这些数据,增大了服务器被攻击的风险。

第三次握手的时候,客户端已经处于ESTABLISHED状态,并且已经能够确认服务器的接收、发送能力正常,这个时候相对安全了,可以携带数据。

什么是SYN洪泛攻击?

SYN洪泛攻击就是利用TCP协议的特性(三次握手)。

攻击者发送TCP的 SYN,SYN是TCP三次握手中第一个数据包,而当服务器返回ACK后,该攻击者就不对其进行再确认,那这个TCP连接就处于挂起状态,也就是半连接状态,服务器收不到再确认的话,还会重复发送ACK给攻击者。

这样更加会浪费服务器资源。攻击者就对服务器发送大量的这种TCP连接,由于每一个连接都无法完成三次握手,所以就在服务器上,这些TCP连接会因为挂起状态而消耗CPU和内存,最后服务器可能死机。

如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP保活计时器 每次客户端请求服务器会重置计时器,当2小时之内没收到客户端任何数据时,会每隔75s向客户端发一个探测报文,若接连发送10个,客户端都没有反应,则认为客户端故障,关闭连接。

四次挥手

为什么最后还要等待两个时间周期呢?

可能造成的问题:

  1. 如果客户端的最后一个ACK报文在传输的时候丢失,服务器并没有接收到这个报文。这个候时候服务器就会超时重传这个FIN消息,然后客户端就会重新返回最后一个ACK报文,等待两个时间周期,完成关闭。

    如果不等待这两个时间周期,客户端直接关闭,服务器重传的那条消息就不会收到。服务器就因为接收不到客户端的信息而无法正常关闭。

  2. 如果不等待,客户端直接跑路,当服务端还有很多数据包在路上的时候,若客户端的端口此时刚好被新的应用占用,那么就接收到了无用数据包,造成数据包混乱。所以,最保险的做法是等服务器发来的数据包都死翘翘再启动新的应用。

    1 个 时间周期确保四次挥手中主动关闭方最后的 ACK 报文最终能达到对端

    1 个 时间周期确保对端没有收到 ACK 重传的 FIN 报文可以到达

为什么是四次挥手而不是三次?

因为服务端在接收到FIN, 仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以服务端可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接。因此先发一个ACK表示已经收到客户端的FIN,等服务端所有数据都发出去了才发FIN。这就造成了四次挥手。

如果是三次挥手,等于说服务端将ACKFIN的发送合并为一次挥手,这个时候长时间的延迟可能会导致客户端误以为FIN没有到达客户端,从而让客户端不断的重发FIN

第二次挥手和第三次挥手之间,如果服务端还需要向客户端发送数据,这时在第二次挥手和第三次挥手合并的情况下,可能会导致服务端还没发送完,客户端就已经关闭。

TCP/UDP协议

TCP如何实现可靠传输?

主要通过以下四种方式实现可靠传输机制:

  • 校验:伪首部是为了增加TCP校验和的检错能力:通过伪首部的目的IP地址来检查TCP报文是否收错了、通过伪首部的传输层协议号来检查传输层协议是否选对了。需要注意的是,伪首部实际上是不存在的,只是用来验证TCP报文是否出错。
  • 序号:之前我们提到TCP是面向字节流的,比如第一个字节就是序号1,第二个字节就是序号2。 而在TCP报文格式,有一个序号字段,这个指的是一个报文段第一个字节的序号。报文段就是你每个数据包。有了序号,就能保证数据是有序的传入应用层。
  • 确认:发送方在收到接收方的确认包之后,才继续发送剩下的数据。
  • 重传:TCP的发送方在规定的时间内没有收到确认就要重传已发送的报文段(超时重传)。重传时间是动态改变的,依据的是RTTS(加权平均往返时间)。

TCP和UDP的区别

  • TCP是面向连接的,udp是无连接的即发送数据前不需要先建立链接。

  • TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,可靠有序,不丢不重;UDP尽最大努力交付,不保证可靠交付。 并且因为tcp可靠,面向连接,不会丢失数据因此适合大数据量的交换。

  • TCP是面向字节流,UDP面向报文,并且网络出现拥塞不会使得发送速率降低(因此会出现丢包,对实时的应用比如IP电话和视频会议等)。

  • TCP只能是1对1的传输,UDP支持1对1,1对多。

  • TCP的首部较大为20字节,而UDP只有8字节。