0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

UDP如何实现可靠传输

科技绿洲 来源:Linux开发架构之路 作者:Linux开发架构之路 2023-11-10 15:19 次阅读

TCP的accept发生在三次握手的哪个阶段?

如下图connect和accept的关系:

accept过程发生在三次握手之后,三次握手完成后,客户端和服务器就建立了tcp连接并可以进行数据交互了。

这时可以调用accept函数获得此连接。

connect返回了可以认为连接成功了吗?

connect返回成功后,三次握手就已经完成了。

已完成的链接会被放入一个队列中,accept的作用就是从已连接队列中取出优先级最高的一个链接,并将它绑定给一个新的fd,服务端就可以通过这个新的fd来recv和send数据了。

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

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

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

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

等待2MSL的意义,如果不等待会怎样?

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

那,照这样说一个 MSL 不就不够了吗,为什么要等待 2 MSL?

  • 1 个 MSL 确保四次挥手中主动关闭方最后的 ACK 报文最终能达到对端
  • 1 个 MSL 确保对端没有收到 ACK 重传的 FIN 报文可以到达

这就是等待 2MSL 的意义。

SYN Flood 攻击

SYN Flood 攻击原理

SYN Flood 属于典型的 DoS/DDoS 攻击。其攻击的原理很简单,就是用客户端在短时间内伪造大量不存在的 IP 地址,并向服务端疯狂发送SYN。对于服务端而言,会产生两个危险的后果:

  1. 处理大量的SYN包并返回对应ACK, 势必有大量连接处于SYN_RCVD状态,从而占满整个半连接队列,无法处理正常的请求。
  2. 由于是不存在的 IP,服务端长时间收不到客户端的ACK,会导致服务端不断重发数据,直到耗尽服务端的资源。

如何应对 SYN Flood 攻击?

  • 增加 SYN 连接,也就是增加半连接队列的容量。
  • 减少 SYN + ACK 重试次数,避免大量的超时重发。
  • 利用 SYN Cookie 技术,在服务端接收到SYN后不立即分配连接资源,而是根据这个SYN计算出一个Cookie,连同第二次握手回复给客户端,在客户端回复ACK的时候带上这个Cookie值,服务端验证 Cookie 合法之后才分配连接资源。

TCP Fast Open

图片

注意: 客户端最后握手的 ACK 不一定要等到服务端的 HTTP 响应到达才发送,两个过程没有任何关系。

第一次握手时server会计算出cookie传给客户端并缓存,之后的握手客户端会携带cookie进行SYN。

如果cookie不合法直接丢弃,如果合法,就可以直接发送http响应。

TFO 的优势

TFO 的优势并不在与首轮三次握手,而在于后面的握手,在拿到客户端的 Cookie 并验证通过以后,可以直接返回 HTTP 响应,充分利用了1 个RTT(Round-Trip Time,往返时延)的时间提前进行数据传输,积累起来还是一个比较大的优势。

序列号回绕怎么办?

现在我们来模拟一下这个问题。

序列号的范围其实是在0 ~ 2 ^ 32 - 1, 为了方便演示,我们缩小一下这个区间,假设范围是 0 ~ 4,那么到达 4 的时候会回到 0。

图片

假设在第 6 次的时候,之前还滞留在网路中的包回来了,那么就有两个序列号为1 ~ 2的数据包了,怎么区分谁是谁呢?这个时候就产生了序列号回绕的问题。

那么用 timestamp 就能很好地解决这个问题,因为每次发包的时候都是将发包机器当时的内核时间记录在报文中,那么两次发包序列号即使相同,时间戳也不可能相同,这样就能够区分开两个数据包了。

附:

timestamp是 TCP 报文首部的一个可选项,一共占 10 个字节,格式如下:

kind(1 字节) + length(1 字节) + info(8 个字节)

其中 kind = 8, length = 10, info 有两部分构成: timestamp和timestamp echo,各占 4 个字节。

能不能说说 Nagle 算法和延迟确认?

Nagle 算法

试想一个场景,发送端不停地给接收端发很小的包,一次只发 1 个字节,那么发 1 千个字节需要发 1000 次。这种频繁的发送是存在问题的,不光是传输的时延消耗,发送和确认本身也是需要耗时的,频繁的发送接收带来了巨大的时延。

而避免小包的频繁发送,这就是 Nagle 算法要做的事情。

具体来说,Nagle 算法的规则如下:

  • 当第一次发送数据时不用等待,就算是 1byte 的小包也立即发送
  • 后面发送满足下面条件之一就可以发了:
  • 数据包大小达到最大段大小(Max Segment Size, 即 MSS)
  • 之前所有包的 ACK 都已接收到

延迟确认

试想这样一个场景,当我收到了发送端的一个包,然后在极短的时间内又接收到了第二个包,那我是一个个地回复,还是稍微等一下,把两个包的 ACK 合并后一起回复呢?

延迟确认(delayed ack)所做的事情,就是后者,稍稍延迟,然后合并 ACK,最后才回复给发送端。TCP 要求这个延迟的时延必须小于500ms,一般操作系统实现都不会超过200ms。

不过需要主要的是,有一些场景是不能延迟确认的,收到了就要马上回复:

  • 接收到了大于一个 frame 的报文,且需要调整窗口大小
  • TCP 处于 quickack 模式(通过tcp_in_quickack_mode设置)
  • 发现了乱序包

两者一起使用会怎样?

前者意味着延迟发,后者意味着延迟接收,会造成更大的延迟,产生性能问题。

TCP的Keep Alive和HTTP的Keep Alive的区别

TCP keepalive

  • 在双方长时间未通讯时,如何得知对方还活着?如何得知这个TCP连接是健康且具有通讯能力的?
  • TCP的保活机制就是用来解决此类问题的
  • 保活机制默认是关闭的,TCP连接的任何一方都可打开此功能。
  • 若对端正常存活,且连接有效,对端必然能收到探测报文并进行响应。此时,发送端收到响应报文则证明TCP连接正常,重置保活时间计数器即可。
  • 若由于网络原因或其他原因导致,发送端无法正常收到保活探测报文的响应。那么在一定探测时间间隔(tcp_keepalive_intvl)后,将继续发送保活探测报文。直到收到对端的响应,或者达到配置的探测循环次数上限(tcp_keepalive_probes)都没有收到对端响应,这时对端会被认为不可达,TCP连接随存在但已失效,需要将连接做中断处理。

HTTP keep-alive

  • keep-alive机制:若开启后,在一次http请求中,服务器进行响应后,不再直接断开TCP连接,而是将TCP连接维持一段时间。在这段时间内,如果同一客户端再次向服务端发起http请求,便可以复用此TCP连接,向服务端发起请求,并重置timeout时间计数器,在接下来一段时间内还可以继续复用。这样无疑省略了反复创建和销毁TCP连接的损耗。

TCP队头阻塞和HTTP队头阻塞

  1. TCP队头阻塞

TCP数据包是有序传输,中间一个数据包丢失,会等待该数据包重传,造成后面的数据包的阻塞。(停止等待)

  1. HTTP队头阻塞

http队头阻塞和TCP队头阻塞完全不是一回事。

http1.x采用长连接(Connection:keep-alive),可以在一个TCP请求上,发送多个http请求。

有非管道化和管道化,两种方式。

非管道化,完全串行执行,请求->响应->请求->响应…,后一个请求必须在前一个响应之后发送。

管道化,请求可以并行发出,但是响应必须串行返回。后一个响应必须在前一个响应之后。原因是,没有序号标明顺序,只能串行接收。

管道化请求的致命弱点:

  1. 会造成队头阻塞,前一个响应未及时返回,后面的响应被阻塞
  2. 请求必须是幂等请求,不能修改资源。因为,意外中断时候,客户端需要把未收到响应的请求重发,非幂等请求,会造成资源破坏。

由于这个原因,目前大部分浏览器和Web服务器,都关闭了管道化,采用非管道化模式。

无论是非管道化还是管道化,都会造成队头阻塞(请求阻塞)。

解决http队头阻塞的方法:

  1. 并发TCP连接(浏览器一个域名采用6-8个TCP连接,并发HTTP请求)
  2. 域名分片(多个域名,可以建立更多的TCP连接,从而提高HTTP请求的并发)
  3. HTTP2方式

http2使用一个域名单一TCP连接发送请求,请求包被二进制分帧**(多路复用)**不同请求可以互相穿插,避免了http层面的请求队头阻塞。但是不能避免TCP层面的队头阻塞。

UDP

UDP如何实现可靠传输?

传输层无法保证数据的可靠传输,只能通过应用层来实现了。

实现的方式可以参照tcp可靠性传输的方式,只是实现不在传输层,实现转移到了应用层。

最简单的方式是在应用层模仿传输层TCP的可靠性传输。

下面不考虑拥塞处理,可靠UDP的简单设计。

1、添加seq/ack机制,确保数据发送到对端

2、添加发送和接收缓冲区,主要是用户超时重传。

3、添加超时重传机制。

详细说明:送端发送数据时,生成一个随机seq=x,然后每一片按照数据大小分配seq。数据到达接收端后接收端放入缓存,并发送一个ack=x的包,表示对方已经收到了数据。发送端收到了ack包后,删除缓冲区对应的数据。时间到后,定时任务检查是否需要重传数据。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 服务器
    +关注

    关注

    12

    文章

    8124

    浏览量

    82538
  • ACK
    ACK
    +关注

    关注

    0

    文章

    27

    浏览量

    11079
  • UDP
    UDP
    +关注

    关注

    0

    文章

    311

    浏览量

    33624
  • 函数
    +关注

    关注

    3

    文章

    3903

    浏览量

    61310
收藏 人收藏

    评论

    相关推荐

    求助关于TCP/UDP传输的问题

    本帖最后由 思想的小鱼 于 2016-5-20 10:47 编辑 楼主完成了UDP和TCP传输的模块,但目的是实现UDP传输和接收命令
    发表于 05-20 10:43

    UDP高速传输问题

    目前小弟在做一个数据采集项目,采集卡(250MSPS采样率)与上位机是UDP实现,1000Mbps的传输速率,采集卡可做两种传输模式,第一种是一次
    发表于 05-24 10:48

    UDP协议用于高性能路由器内部通信的设计与实现

    UDP 是一种应用广泛的传输协议,具有传输速度快、简单等特点,但其面向无连接的特性,使得应用UDP 传输具有不
    发表于 07-30 10:01 21次下载

    基于UDP协议的语音传输系统设计及实现

    摘 要:文中讨论了基于UDP协议的语音传输系统的设计及实现。比较详细的阐述了语音信息的录制和播放、发送接收、压缩和解压缩以及语音传输过程的缓冲机制。由于采用了压缩技
    发表于 07-02 21:51 44次下载

    实现基于51单片机的UDP实时传输工具

    实现基于51单片机的UDP实时传输工具
    发表于 09-21 13:40 7次下载
    <b class='flag-5'>实现</b>基于51单片机的<b class='flag-5'>UDP</b>实时<b class='flag-5'>传输</b>工具

    udp常用端口号有哪些

    UDP提供了无连接通信,且不对传送数据包进行可靠性保证,适合于一次传输少量数据,UDP传输可靠
    发表于 12-08 09:18 12.9w次阅读
    <b class='flag-5'>udp</b>常用端口号有哪些

    udp协议设计与实现

    UDP协议功能 无连接传输 : 不保证端到端数据传输可靠性 , 一定程度上保证 了数据传输实时性 , 适合多媒体数据
    发表于 08-04 14:24 12次下载

    基于UDP的简单文件传输协议TFTP设计

    前面我们已经实现UDP的回环客户端和回环服务器的简单应用,接下来我们实现一个基于UDP的简单文件传输协议TFTP。
    的头像 发表于 12-14 15:06 1751次阅读
    基于<b class='flag-5'>UDP</b>的简单文件<b class='flag-5'>传输</b>协议TFTP设计

    UDP能否像TCP一样实现可靠传输

    UDP (User Datagram Protocol)是一种无连接的协议,基于数据报的传输方式。在网络通信中,它通常用于快速传输数据包,但却无法保证数据包的可靠
    的头像 发表于 06-05 09:48 474次阅读
    <b class='flag-5'>UDP</b>能否像TCP一样<b class='flag-5'>实现</b><b class='flag-5'>可靠</b><b class='flag-5'>传输</b>?

    UDP能否像TCP一样实现可靠传输

    连接的协议,基于字节流的传输方式。它通过确认和重传等机制来保证数据的完整性和顺序性,实现数据包的可靠传输UDP与TCP的主要区别但在某些运
    的头像 发表于 06-08 14:50 629次阅读
    <b class='flag-5'>UDP</b>能否像TCP一样<b class='flag-5'>实现</b><b class='flag-5'>可靠</b><b class='flag-5'>传输</b>?

    udp是什么协议 TCP与UDP的区别

    TCP协议提供可靠的数据传输UDP协议提供尽量高效的数据传输。TCP协议通过使用序列号、确认应答等机制,保证数据传输
    的头像 发表于 06-26 17:47 7095次阅读

    TCP和UDP如何实现可靠传输

    TCP(TransmissionControl Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
    的头像 发表于 10-16 14:19 395次阅读
    TCP和<b class='flag-5'>UDP</b>如何<b class='flag-5'>实现</b><b class='flag-5'>可靠</b>性<b class='flag-5'>传输</b>

    如何选择传输层协议?TCP和UDP的优缺点和适用场合

    可靠性至关重要。本文将详细介绍TCP和UDP的优缺点以及适用场合。 1. TCP的优点和适用场合: TCP是一种可靠的、面向连接的传输层协议,它提供了重发机制、数据丢失检测和拥塞控制
    的头像 发表于 12-11 11:42 474次阅读

    UDP与TCP的主要区别 UDP能否像TCP一样实现可靠传输

    UDP与TCP的主要区别 UDP能否像TCP一样实现可靠传输?TCP如何实现
    的头像 发表于 01-22 16:10 188次阅读

    udp是什么协议?udp协议介绍

    UDP(User Datagram Protocol,用户数据报协议)是一种无连接的传输层协议,不保证数据传输可靠性,只负责把数据包发送给目标地址。它提供了简单、高效的数据
    的头像 发表于 04-19 15:57 120次阅读