【传输层协议】UDP和TCP协议

UDP协议

UDP协议全称为User Datagram Protocol,用户数据报协议。UDP协议报文格式如下:
在这里插入图片描述

  • 16UDP长度。表示整个数据报的最大长度,即UDP首部+UDP数据。这个字段帮助我们确保在网络字节流中获取完整的UDP报文信息
  • 校验和:用于检测数据报在传输过程中是否发生错误。

UDP特点

  • 无连接:UDP不需要建立连接就可以发送数据,这意味着在发送数据之前,发送方和接收方并没握手过程
  • 不可靠传输:UDP不保证数据包的到达顺序,也不保证数据包一定到达(没有应答)。这意味着数据包可能丢失了都不知道或者乱序达到。
  • 低开销:因为不用维护连接,也不用保证传输的可靠性,UDP的报头只有8字节,开销比较小。
  • 面向数据报:面向数据报又叫面向消息。面向数据报的意思就是应用层给UDP多少数据,UDP的数据部分就有多少,既不会拆分也不会合并(不灵活)
  • 传输的数据量少:16位长度包括首部也就64k,相当有限。如超过这个范围就需要在应用层手动分包,多次发送,接收后也要采取手段拼装。

UDP的缓冲区

  • UDP没有真正意义上的发送缓冲区,调用sendto会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作。
  • UDP具有接收缓冲区。但是这个接收缓冲区不能保证收到的UDP报文和发送报文的顺序。如果缓冲区满了,再到达的UDP报文就会直接被丢弃。
  • UDP 的 socket 既能读, 也能写, 所以是 全双工

基于UDP的应用层协议

  • NFS:网络文件系统
  • TFTP:简单文件传输协议
  • DHCP:动态主机配置协议
  • BOOTP:启动协议(用于无盘设备启动)
  • DNS:域名解析协议

TCP协议

TCP协议的全称为传输控制层协议(Transmission Control Protocol)。下面是TCP报文的结构:
在这里插入图片描述
显然,TCP报文首部要包含的信息比UDP多很多,下面来分析各个字段的作用。

  • 源/目的端口号: 表示数据是从哪个进程来, 到哪个进程去

  • 32位序号:表示发送数据的字节序号,用于数据重组,该字节序号与发送缓冲区的字节序相关联

  • 32位确认序号仅在ACK标志置位时有效,表示期望接收的下一个字节序号。

  • 4 位 TCP 报头长度:表示TCP头部的长度(以4字节为单位),最小值为5。也就是说如果这4位报头长度的为5,那么实际表示报头的长度就是5*4=20字节。

  • 6位标志位:

    • URG:紧急指针有效。
    • ACK:确认号有效。
    • PSH:提醒接收方尽快读取接收缓冲区的数据
    • RST:重置连接,携带该标志的报文也称为复位报文段
    • SYN:同步序号,用户建立连接,携带该标志位的报文也称为同步报文段
    • FIN:表示发送方已经发送完毕,需要关闭连接,携带该标志位的报文也称为结束报文段
  • 16位窗口大小:表示接收方的窗口大小,用于流量控制。如果该值比较大,那就可以一次多发点报文,否则就一次少发一下。

  • 16 位校验和: 发送端填充, CRC 校验. 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含 TCP 首部, 也包含 TCP 数据部分

  • 16 位紧急指针: 一个偏移量,标识哪部分数据是紧急数据。这个指针只在URG标记位为1时生效。

  • 40 字节头部选项: 可变长度,用于定义附加选项,比如最大报文段长度(MSS)、时间戳等。假如窗口大小大于16位,就可以附加增大窗口大小的选项。

确认应答机制

TCP为了保证数据传输的可靠性,在每次发送端发送数据之后**,接收端要发送一个携带ACK标记位的报文(后面简称为ACK),来告诉发送端消息已经收到**。这也就意味着,只要发送端收到了ACK,就可以继续发后面的数据了。
在这里插入图片描述
TCP 将每个字节的数据都进行了编号. 即为序列号,如下图:
在这里插入图片描述
每一个 ACK 都带有对应的确认序列号, 意思是告诉发送者, 我已经收到了哪些数据; 下一次你从哪里开始发.假如发送方发送了字节序号为1-1000的数据,也就是说16位发送序号为1000。当接收方收到数据后,根据发送序号,再发送一个确认序号为1001的ACK报文,提醒发送方1001之前的字节数据已经收到,下次应该发送1001号字节开始往后的数据。

超时重传机制

在这里插入图片描述

如果发送端发送报文之后长时间没有收到接收端发过来的ACK,那么说明可能是由于网络拥堵丢包了根本没到达接收端,也有可能接收端已经收到且发送了ACK,只不过ACK由于某种原因丢失了。这个时候发送端就会重新发送一个一模一样的报文。这种机制就称为超时重传机制
关于超时重传,解释以下几点:

  • 如果接收端收到了重复的数据该怎么处理呢?
    根据报文中的序列号排序,如果该序列号的数据已经有了,那接收方就直接丢弃这个多余的报文。

  • 超时的时间该如何确定?

最理想的情况下, 找到一个最小的时间, 保证 “确认应答一定能在这个时间内返回”.但是这个时间的长短, 随着网络环境的不同, 是有差异的。
为了保证无论在任何环境下都能比较高性能的通信, 因此会动态计算这个最大超时时间: Linux中,超时以 500ms 为一个单位进行控制, 每次判定超时重发的超时时间都是 500ms 的整数倍. 如果重发一次之后, 仍然得不到应答, 等待 2*500ms 后再进行重传.如果仍然得不到应答, 等待 4*500ms 进行重传. 依次类推, 以指数形式递增.
累计到一定的重传次数, TCP 认为网络或者对端主机出现异常, 强制关闭连接.

连接管理机制(握手和挥手)

在正常情况下, TCP 要经过三次握手建立连接, 四次挥手断开连接。具体过程如下图:
在这里插入图片描述

服务端状态转换过程

  • [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, 彻底关闭连接.(收到第四次挥手)

客户端状态转换过程

  • [CLOSED -> SYN_SENT] 客户端调用 connect, 发送同步报文段(发起第一次握手
  • [SYN_SENT -> ESTABLISHED] connect 调用成功(收到第二次握手), 则进入 ESTABLISHED 状态。发送ACK给服务端(发起第三次握手),开始读写数据
  • [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状态

TCP 协议规定,主动关闭连接的一方要处于 TIME_ WAIT 状态,等待两个MSL(maximum segment lifetime)的时间后才能回到 CLOSED 状态.此时已经发起了第四次挥手,为了保证这个第四次挥手能被接收方接收到,所以需要等待一段时间。当然,这个ACK也有可能丢失,那么服务器会再重发一个 FIN
MSL 在 RFC1122 中规定为两分钟,但是各操作系统的实现不同, 在 Centos7 上默认配置的值是 60s;
这也是为什么有时候主动关闭服务端,马上重启不能绑定同样的端口。这是因为上一个关闭的服务端可能还处于TIME_WAIT状态,还没有彻底的断开连接释放套接字。

同时,等待一定的时间再关闭套接字,也是为了两个传输方向上还没有被接收的数据的报文段都已经消失,保证下次重启同一个端口的服务器不会收到旧数据

CLOSE_WAIT状态

如果服务端第一次收到客户端发来的FIN报文,发送ACK报确认后服务端就会进入CLOSE_WAIT状态。此时服务端已经知道对方要关闭连接了,自己也要准备关闭了。

在这个状态下的服务端依旧可以向客户端发送数据报,虽然客户端关闭了连接,但依旧可以收报文(接收缓冲区没有关闭)。直到服务端调用close函数,才会结束这个状态。如果应用程序没有及时调用close函数,连接会长时间停留在CLOSE_WAIT状态。这样就会导致资源泄露(如文件描述符耗尽),影响服务器性能

为什么是三次握手和四次挥手

换个问题,为什么三次握手就能保证建立可靠的连接呢?

  • 确认对方主机状态及收发能力的最小次数。三次握手保证了双方网络的连通性,也保证了双方连接的意愿,还保证了双方拥有接收和发送数据的能力。
  • 如果只有一次握手,意味着只要发送方发送连接请求,连接就会被建立。那这样服务端容易收到SYN洪流攻击,即服务端建立大量的连接对象消耗太多资源从而导致奔溃。两次握手也是类似,服务端收到一次连接,只要服务端发出一次ACK,就说明连接就建立起来了(发送方可以不要这个ACK,而是只发SYN)。如果有不法分子恶意发送大量的SYN,服务器依旧会创建对应的连接对象,依旧非常消耗资源。
  • 如果是三次握手,客户端建立连接和服务端建立连接的代价是一样的,同样需要发送ACK,否则连接就会失败。也就是说,双方是对等的,变相的客户端连接的成本提高了,也就不容易搞垮服务器
  • 四次握手也可以,只不过再多的握手达到的效果和三次是一样的,那为什么还要浪费时间去多握手呢?

为什么是四次挥手而不是像握手一样进行三次挥手?
因为当客户端发起第一次挥手之后,只是意味着不再向服务端端发送数据包,不代表不能接收数据包。有可能服务端处理的数据包还没被客户端接收,此时彻底关闭连接就丢失数据了。所以客户端需要有一个时间间隔来读取服务端发送的数据包,什么时候接收方发送完了呢?就是等服务端也发起挥手的时候,此时就代表服务端发送完了,客户端也不需要再收取数据了。

同样的,四次挥手保证了通信双方都有关闭连接的行为,且都能得到应答,也就是说对方都能知道你要退出。这样就保证了数据传输的完整性。

五次挥手?和不需要四次握手是一样的道理。

滑动窗口

滑动窗口是TCP保证传输效率的一个重要手段。具体来说,滑动窗口维护了一个报文区间,处于这个区间的报文都可以暂时不考虑应答直接全部发送。如下图。在这里插入图片描述
更详细的:

  • 窗口大小指的是无需等待确认应答而可以继续发送数据的最大值. 上图的窗口大小就是 4000 个字节(四个段).
  • 收到第一个 ACK 后, 滑动窗口向后移动, 继续发送第五个段的数据;窗口向右移动。
  • 窗口越大, 则网络的吞吐率就越高

在这里插入图片描述
对于滑动窗口,解释以下几点:

如果发生丢包如何进行重传?

由于一次发送多个报文,丢包的概率就会上升。那么发生丢包之后如何进行重传呢?下面分情况讨论。

  • 情况一:数据包到达,但是ACK确认 丢了
    在这里插入图片描述

回顾之前TCP报文中的确认序号的作用,即告诉发送端下一次发送数据应该从哪个字节序开始,换句话来说,假设ACK的确认序号为2001,则表示1-2000的数据全部都收到了。这样一来,即使中间有ACK丢失,只要后面有ACK没有丢那就不影响。比如确认序号为2001、3001的ACK都丢失了,但是4001没有丢失,那么接收端就会认为4000以前的数据都被收到了,即使没有收到2001和3001的ACK

  • 情况二:数据包丢失
    这种情况接收方并没有收到部分数据包,也就不会发送ACK应答。假设前面字节序的数据包丢失,接收端在收到靠后的数据包后,通过对数据包排序会检测最前面还没有收到的字节序,并以此发送ACK。例如:
    在这里插入图片描述
    上图中一次发送了7个数据包,发送序号依次为1000、2000到7000。现在第2个数据包丢失,即发送序号为2000,接收方只收到了字节序1000和3000-7000的数据,这个时候,接收方发现最前面的2000个字节的数据还没有收到,发送的ACK的确认序号就是1001,表示1001以前的数据全部收到。为什么不发送3001或者7001呢?这是因为如果发送ACK的确认序号为3001的话,发送方就会认为1-3000的数据都被成功接收了,可实际上不是。也就是说,7个报文中,最后接收方成功收到了6个报文,且这6个报文的ACK全部都是1001
    当发送方连续收到的3个相同的1001ACK时,就会重新发送1001-2000的数据包。这种机制就称为高速重发控制,也称为快重传。为什么说是高速呢?因为这种机制减少了发送端的等待重传的时间。当然,如果没有收到3个,即最后只有两个报文丢失了前面的一个,这个时候发送方就会超时重传利用快重传和超时重传,即保证了数据传输的可靠性,也一定保证了传输的速度

流量控制

接收端处理数据的速度是有限的,如果发送端发送的太快就会导致接收端的接收缓冲区打满。这个时候如果发送方继续发送数据包就会造成丢包。
TCP支持根据接收端的处理能力, 来决定发送端的发送速度. 这个机制就叫做流量控制
具体是怎么做到的呢?
上面我们已经说过,TCP报文中用16位比特位表示窗口大小,由于窗口是根据接收方的实际接收缓冲区变化而变化的。所以,如果收到的报文中窗口大小字段比较大,那么说明接收方的接收缓冲区还有很多剩余空间,这个时候就可以一次多发一点数据包,否则就可以少发一点。这样就达到了控制流量的效果。

此外,如果接收端的缓冲区满了,就会把窗口值设为0。这时发送方不再发送数据, 但是需要定期发送一个窗口探测数据段, 使接收端把窗口大小告诉发送端.也可以设置PSH标记位来提醒接收端快点从缓冲区里读数据
在这里插入图片描述
本质上,所谓的窗口探测报文就是一个极少数据量的TCP数据包,和普通报文没区别,只是为了获得ACK的窗口大小

拥塞控制

虽然 TCP 有了滑动窗口这个大杀器, 能够高效可靠的发送大量的数据. 但是还可能会受到网络情况的影响。比如网络现在比较拥堵即使接收方的窗口大小还很大,发送方发来的数据被堵在网络中,依旧达不到高效传输的目的,而且还很有可能加重拥堵。为了解决这个问题,或者说避免加重有拥堵,引入拥塞窗口的概念。

既然接收缓冲区的窗口大小直接表示了缓冲区接受数据的能力,那么拥塞窗口的大小也能直接表示当前网络的拥塞情况,拥塞窗口越大表示网络越不拥堵,相反则越拥堵

那发送方如何根据拥塞窗口来调整自己的发送数据包的量呢?

  • 如果发送方总是收不到ACK,那么说明丢包率比较高,此时就可以判断网络已经阻塞了。
  • 此时就不能发送太多的数据包,否则就会加重阻塞。开始发送一个数据包,并定义拥塞窗口的大小为1,每次收到一个 ACK 应答, 拥塞窗口加 1;
  • 每次发送数据包的时候, 将拥塞窗口和接收端主机反馈的窗口大小做比较, 取 较小的值 作为实际发送的窗口;

慢启动

慢启动是TCP拥塞控制的一部分,用于在连接建立或重传超时后逐步增加拥塞窗口的大小,以避免网络拥塞。与其名称相反,慢启动的实际增长速度非常快。(只是指开始启动慢)

发送方每次发送的报文数量是上一次的的两倍,即2的n次方的速度增长。具体过程如下图:
在这里插入图片描述

  • 但是指数增长的太快了,为了限制增长速度,需要设置一个慢启动阈值。慢启动阈值是一个预设值,用于限制慢启动阶段的指数增长,当拥塞窗口的大小达到了阈值,就不再按照指数方式增长, 而是按照线性方式增长
  • 当 TCP 开始启动的时候, 慢启动阈值等于窗口最大值;
  • 如果又遇到了网络阻塞,就会重新慢启动,且本次慢启动的阈值是上一次最大拥塞窗口的一半。

延迟应答

如果接收数据的主机立刻返回 ACK 应答, 这时候返回的窗口可能比较小.此时可以采用延迟应答,即不立刻返回ACK,而是等一下,等待的时间里可能接收端会从从缓冲区中处理一些数据,到时候发送的ACK的窗口大小就会大一点,发送方收到后也就可以多发一点数据包。

当然,延迟的时间肯定不能太长(有最大延迟时间),不然发送端就超时重发了。
在这里插入图片描述

捎带应答

如果接收方收到了发送方的数据包,发送的ACK报文可以携带其它的数据,从而减少单独发送确认报文的次数。这就叫做捎带应答。比如第二次握手的过程,就是ACK标记位和SYN标记位一起生效发给接收方
在这里插入图片描述
为什么第二次挥手的时候不能使用捎带应答的方式来减少挥手次数呢?
这是因为,服务器收到FIN报文后,发送一个ACK报文确认接收到了客户端的FIN报文,同时服务器可能还在发送一些未完成的数据。也就是说,即使收到发送方的关闭请求,服务器还是需要向接收方发送消息,中间需要时间

粘包问题

粘包是指在接收端读取数据时,可能会将多个发送端的数据包拼接在一起(粘在一起),或将一个数据包拆成多次读取。这通常发生在基于流的传输协议(如TCP)中。

每个UDP数据包都是一个独立的报文,具有明确的边界。因此,UDP协议本身不会出现粘包问题。每次调用recvfrom或recv函数时,都会接收到一个完整的UDP数据包。
但是TCP接收方按照固定长度读取数据,就可能读取不完整或者是一次读取多个数据包。因此需要使用特殊字符(如换行符、空格等)作为数据包之间的分隔符。接收方根据特殊字符来拆分数据包

总结TCP

为什么 TCP 这么复杂? 因为要保证可靠性, 同时又尽可能的提高性能.

  • 可靠性:校验和、序列号(按序到达)、确认应答、超时重发、连接管理、流量控制、拥塞控制
  • 传输效率:滑动窗口、快速重传、延迟应答、捎带应答

基于TCP的应用层协议:

  • HTTP
  • HTTPS
  • SSH
  • Telent
  • FTP
  • SMTP

对比TCP和UDP

TCP 是可靠连接, 那么是不是 TCP 一定就优于 UDP 呢? TCP 和 UDP 之间的优点和缺点, 不能简单, 绝对的进行比较.我们需要根据实际的场景来选择合适的协议。

  • TCP 用于可靠传输的情况, 应用于文件传输, 重要状态更新等场景
  • UDP 用于对高速传输和实时性要求较高的通信领域, 例如, 早期的 QQ, 视频传输等. 另外 UDP 可以用于广播;
  • 如果不知道使用什么传输层协议,那就优先考虑TCP

如何用UDP实现可靠传输(面试题目)

参考 TCP 的可靠性机制, 在应用层实现类似的逻辑;
比如:

  • 引入序列号,保证数据顺序
  • 引入确认应答,确保收到了数据
  • 引入超时重传, 如果隔一段时间没有应答, 就重发数据;
  • 引入窗口大小,控制流量
  • 等等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/387496.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

巴斯勒相机(Basler) ACE2 dart 系列说明和软件

巴斯勒相机(Basler) ACE2 dart 系列说明和软件

C语言指针·入门用法超详解

目录 1. 什么是指针 2. 指针变量的定义格式 3. 指针的作用 3.1 查询数据 3.2 存储数据(修改数据) 3.3 操作其他函数中的变量 3.4 函数返回多个值 3.5 函数的结果和计算状态分开 1. 什么是指针 通过内存地址,指向的空间&#…

vue3后台管理系统 vue3+vite+pinia+element-plus+axios上

前言 项目安装与启动 使用vite作为项目脚手架 # pnpm pnpm create vite my-vue-app --template vue安装相应依赖 # sass pnpm i sass # vue-router pnpm i vue-router # element-plus pnpm i element-plus # element-plus/icon pnpm i element-plus/icons-vue安装element-…

C++第一篇 入门基础

目录 1.C的第一个程序 2.c历代版本 3.命名空间 3.1 namespace关键字 namespace的用法: namespace中定义函数 namespace中定义结构体 C中的域: 3.2就近原则 4.命名空间的使用 5.C输入输出 6.缺省参数 全缺省: 半缺省:必须从右往左连续缺省(也…

爆“卷”的AI视频,大厂向左,创企向右

文|白 鸽 编|王一粟 “生成的人物一转身就变成老外,怎么解决呢?” “没有办法,10s中动作大的,人物一致性有问题,只能抽卡,多刷几个,选择一个变化不大的。” 在一个以…

RocketMQ Server Windows安装

RocketMQ阿里开发 开源给apache 官网:RocketMQ 官方网站 | RocketMQ 下载后解压 配置环境变量 注意启动顺序 双击 注意 4.9.0这个版本必须 jdk 8 高了用不了 namesrv是注册中心的作用 broke是核心用于接收生产者消息 存储消息 发送给消费者消息 类似DubboZookeeper…

Java红娘相亲交友平台系统源码小程序

💕遇见真爱,从“红娘相亲交友平台系统”开始!👫 🌹【精准匹配,缘分不再擦肩而过】 还在为茫茫人海中找不到那个TA而烦恼吗?“红娘相亲交友平台系统”利用先进的大数据分析技术,根据…

匿名内部类

一个类的内部又完整的嵌套了另一个类结构,被嵌套的类称为内部类,嵌套其他的类称为外部类。 类的五大成员:属性、方法、构造器、代码块、内部类 内部类最大的特点的就是直接访问私有属性,并且可以体现类鱼类之间的包含关系。 基本…

北斗三号海上人员落水报警及示位搜救系统升级方案

随着海洋经济的快速发展,海上作业活动日益频繁,人员安全问题也日益凸显。传统的海上救援手段存在诸多不足,如救援响应时间长、定位不准确等。为了提高海上救援的效率和成功率,北斗三号海上人员落水报警及示位搜救系统应运而生。该…

微波传感器 - 从零开始认识各种传感器【第二十期】

微波传感器|从零开始认识各种传感器 1、什么是微波传感器 微波传感器是一种利用微波技术进行探测和测量的传感器。 一般来说,微波是波长为1到1000毫米的电磁波。使用微波传感器,在不接触目标物体的情况下,通过检测和分析微波信号的反射、散…

Matplotlib柱形图大揭秘:让数据‘站’起来,比增高鞋垫还管用!

1. Matplotlib绘制柱形图/柱状图/条形图 柱状图是一种用矩形柱来表示数据分类的图表,柱状图可以垂直绘制,也可以水平绘制,它的高度与其表示的数据成正比关系 # 导包 import numpy as np import pandas as pd import matplotlib.pyplot as p…

机械学习—零基础学习日志(高数16——函数极限性质)

零基础为了学人工智能,真的开始复习高数 这里我们继续学习函数极限的性质。 局部有界性 充分条件与必要条件 极限存在是函数局部有界的充分条件。什么是充分条件,什么是必要条件呢?我这里做了一点小思考,和大家分享&#xff0c…

Windows11下 Visual Studio 2022 + Qt6 的 WebSocket 线程池异步 客户端

Windows11下 Visual Studio 2022 + Qt6 的 WebSocket 线程池异步 客户端 1 开发 WebSocket 客户端1.1 开发环境1.1.1 为Qt 6安装 websockets1.2 .基于Qt6的 QWebSocket 客户端示例1.2.1 实现 WebSocket 客户端1.2.2 创建 QtQWesocketClient1.2.3 创建QWebsocket对象1.2.3.1 添加…

iOS object-C 解答算法:找到所有数组中消失的数字(leetCode-448)

找到所有数组中消失的数字(leetCode-448) 题目如下图:(也可以到leetCode上看完整题目,题号448) 光看题看可能有点难以理解,我们结合示例1来理解一下这道题. 有8个整数的数组 nums [4,3,2,7,8,2,3,1], 求在闭区间[1,8]范围内(即1,2,3,4,5,6,7,8)的数字,哪几个没有出现在数组 …

新装centos7虚拟机如何配置网络,NAT配置固定IP

首先声明,我想使用的是NAT连接模式,并且设置完IP之后,使得这个IP固定住,以后不会再变了。 文章目录 1,打开Vmware软件的【编辑】-【虚拟网络编辑器】2,先选择VMnet8(画1处)&#xf…

解析capl文件生成XML Test Module对应的xml工具

之前一直用的CAPL Test Module来写代码,所有的控制都是在MainTest()函数来实现的,但是有一次,代码都写完了,突然需要用xml的这种方式来实现,很突然,之前也没研究过,整理这个xml整的一身汗&#…

Hive3:库操作常用语句

1、创建库 create database if not exists myhive;2、选择库 use myhive;3、查看当前选择的库 SELECT current_database();4、查看库详细信息 desc database myhive;可以查看数据文件在hdfs集群中的存储位置 5、创建库时制定hdfs的存储位置 create database myhive2 …

安全防护软件的必要性:从微软蓝屏事件谈起

最近微软遭遇了的大规模蓝屏事件,让全球很多用户措手不及。这次事件告诉我们,保护我们的电脑和数据,安全防护软件是多么重要。 微软蓝屏事件源于网络安全公司CrowdStrike的技术更新错误,导致全球范围内大量Windows用户系统崩溃&a…

什么是五力分析?5分钟带你了解它在企业财务经营中的应用与价值!

如今,随着全球化进程的不断加速,市场环境复杂多变,市场竞争日益激烈,财务经营已经成为了企业应对复杂市场环境、保持自身竞争力的关键。体系化的五力分析平台能够为企业提供一套全面的解决方案,帮助企业在盈利能力、偿…

HamonyOS性能优化工具和方法

性能优化,如何做到更快的启动、更流畅的使用,概括图如下 ArkTS高性能编程: 1. ArkTS规则:有利于方舟编译运行时进行编译优化 2. 使用AOT(Ahead Of Time)模式对应用进行编译优化:方舟编译运行时通过采用PGO(Profile-Gui…