【计算机网络】UDP 协议详解及其网络编程应用
文章目录
- 一、引言
- 二、UDP
- 1、UDP的协议格式
- 2、UDP 报文的解包和分用
- 3、UDP面向数据报的特点
- 三、UDP输入输出
- 四、UDP网络编程
一、引言
UDP(User Datagram Protocol,用户数据报协议)是一种网络通信协议,它属于传输层的协议。是一个简单的、面向无连接的协议。UDP用于将数据从一个应用程序发送到另一个应用程序,并在此过程中不提供可靠的数据传输保障。UDP 支持一对一、一对多、多对多的交互通信。
UDP是不具有可靠性的协议。细微的处理它会交给上层的应用去完成。在使用UDP的情况下,虽然可以确保发送消息的大小(例如,发送端应用程序发送一个100字节的消息,那么接收端应用程序也会以100字节为长度接收数据。UDP中,消息长度的数据也会发送到接收端,因此在发送的消息中不需要设置一个表示消息长度或间隔的字段信息。然而,UDP不具备可靠传输。所以,发送端发出去的消息在网络传输途中一旦丢失,接收端将收不到这个消息。) ,却不能保证消息一定会到达。因此,应用有时会根据自己的需要进行重发处理。
UDP不提供复杂的控制机制,利用 IP 提供面向「无连接」的通信服务。
就是说UDP是依赖于底层的IP协议来进行数据传输。IP提供了基本的无连接数据传输服务,UDP在此基础上构建,只是增加了端口号等基本的传输控制功能,但不提供额外的可靠性或连接管理。
由于UDP面向无连接,它可以随时发送数据。再加上UDP本身的处理既简单又高效,因此经常用于以下几个方面:
- 包总量较少的通信(DNS、SNMP等)
- 视频、音频等多媒体通信(即时通信)
- 广播通信(广播、多播)
- 限定于LAN等特定网络中的应用通信
二、UDP
系统调用接口:网络套接字编程接口位于应用层和传输层之间,是操作系统提供的系统调用接口。它允许应用程序通过一组标准的接口进行网络通信,比如 socket()、bind()、sendto()、recvfrom() 等函数。
内核中的UDP:UDP是由操作系统内核实现的,它属于操作系统协议栈的一部分。UDP的所有功能(如数据报的发送和接收)都是由操作系统负责的,而不是由用户应用程序编写的。
协议栈:操作系统内核提供了完整的网络协议栈,其中包括各种网络协议(如IP、TCP、UDP等)。操作系统通过这些协议栈管理网络通信的底层细节,确保网络数据能够在系统和网络之间正确传输。
网络作为操作系统的一部分:网络功能是操作系统的一部分,因为网络协议的实现和管理都在操作系统内核中完成。操作系统通过提供网络套接字接口,让应用程序可以利用这些内核级别的网络功能进行通信。
网络套接字编程接口提供了一个在应用层与操作系统之间的桥梁,使得应用程序能够使用底层的网络协议(如TCP和UDP)进行通信。HTTP等高层协议利用这些底层协议的特性来实现其功能,而UDP作为内核中的协议,由操作系统负责其实现和管理。这种分层设计使得网络编程变得更加灵活和高效。
1、UDP的协议格式

UDP数据段的长度为16位,也就是说UDP能传输的最大长度是64K(包括UDP首部字段)。
若传输的数据超过64K,就需要在应用层手动分包,多次发送,并在接收端手动拼装。
校验和(Checksum):用于检测数据在传输过程中是否被篡改或损坏。它是 UDP 首部和数据部分的 16 位字的反码和。这个字段在某些实现中可能是可选的(可以为 0),但在 IPv6 中是强制的。
UDP报头在内核中的实现:

这个结构体UDPhdr用于表示UDP(用户数据报协议)报头,它通常用于网络编程中。下面是这个结构体中各个字段的含义:
source:源端口号,占16位,表示发送方的端口号。dest:目的端口号,占16位,表示接收方的端口号。len:UDP长度,占16位,包括UDP头部和UDP数据的总长度。check:校验和,占16位,用于检测UDP数据在传输过程中是否出现错误。
这个结构体通常用于原始套接字编程,或者在网络协议的实现中。
2、UDP 报文的解包和分用
1. 报文解包
当UDP报文从网络层传递到传输层时,解包过程会解析UDP首部并提取相应的信息:
- 接收数据报:网络层将接收到的IP数据报传递给传输层。
- 解析UDP首部:传输层解析UDP数据报的前8个字节,从而获取源端口、目的端口、报文长度和校验和。
- 校验和验证:通过计算校验和验证数据报的完整性。如果校验和不匹配,数据报会被丢弃。
- 提取数据部分:从UDP数据报中提取实际的数据部分,将其交给上层应用。
2. 分用
分用是指将接收到的数据报根据目的端口号分配给不同的应用程序。具体步骤如下:
- 检查目的端口:解析出的目的端口号用于确定数据报应该交给哪个应用程序。
- 查找对应的进程:操作系统维护一个端口号到进程的映射表,通过目的端口号查找到相应的进程。
- 传递数据:将数据报的内容传递给相应的应用程序。
UDP的报头当中只包含四个字段,每个字段的长度都是16位,总共8字节。因此UDP采用的实际上是一种定长报头,UDP在读取报文时读取完前8个字节后剩下的就都是有效载荷了。
3、UDP面向数据报的特点
UDP传输过程类似于寄信。
-
无连接性
UDP是无连接的,意味着发送方和接收方之间不需要建立或维护连接。在UDP中,每个数据报文(数据报)都是独立的,不依赖于前后的数据报。这种无连接特性使UDP特别适合需要快速传输的应用程序,如实时视频流、在线游戏等。
-
数据报独立性与无序性
在UDP中,每个数据报都是一个独立的单元。数据报之间没有顺序关系,即使发送顺序被打乱或丢失,也不会影响其他数据报的传输。应用程序必须自行处理数据报的顺序、丢失和重复等问题。而且不保证数据报按发送顺序到达接收端。每个数据报独立传输,接收端收到的数据报可能是乱序的。应用程序需要根据需求自行处理数据的顺序。
-
不可靠
没有确定机制,没有重传机制;若因为网络故障该段无法发送到对方,UDP协议层也不会给应用层返回任何错误信息。UDP没有提供重传机制。如果数据报在传输过程中丢失或损坏,UDP不会自动重传数据。应用程序必须自行处理这些问题,这使得UDP在需要高实时性但对数据可靠性要求不高的场景中非常有效。
如何理解UDP是面向数据报的
UDP(用户数据报协议)是一种无连接、面向数据报的传输层协议。它的设计使其高效且适用于需要快速传输但不需要可靠性保证的应用。
由于UDP提供的是无连接的服务,因此UDP客户与服务之间不存在任何的长期关系。举例来说,一个UDP客户可以创建一个套接字并发送数据报给一个特定的服务器,然后立即用同一个套接字发送另一个数据报给另一个服务器。同样的,一个UDP服务器可以用同一个UDP套接字从若干个不同的客户接收数据报,每个客户一个数据报。
UDP面向数据报的实现:
-
数据报传输:在UDP中,每个数据报从发送端到接收端是独立传输的。发送端将数据封装成UDP数据报,通过网络层(IP层)发送到接收端。接收端接收数据报后,提取出UDP首部信息和数据部分,然后将数据交给相应的应用程序处理。
-
报文解包:在接收端,UDP首部被解析以获取源端口、目的端口、数据长度和校验和等信息。然后,数据部分被提取出来,根据目的端口号将数据传递给相应的应用程序。
-
分用:接收端使用目的端口号来确定哪个应用程序应该接收数据报。这种方式被称为分用。操作系统会维护一个端口号到应用程序的映射表,通过查找表将数据报传递给正确的应用程序。
UDP被称为面向数据报的协议,原因如下:
- 独立的数据报:每个UDP数据报独立存在,彼此之间没有联系。这种设计意味着数据报可以独立处理和传输,无需依赖其他数据报的状态。
- 无连接和无状态:UDP不维护连接状态,也不跟踪数据报的传输状态。这使得每个数据报的传输过程独立,不需要为连接的建立、维护或终止花费额外的开销。
- 简单的首部:UDP首部非常简洁,仅包含必要的信息,使得数据报的处理和解析速度非常快。
- 不保证可靠性:UDP不保证数据报的可靠传输、不丢失、按序到达。这意味着每个数据报的处理是独立的,不依赖于前后数据报的传输状态。
这些特性使UDP非常适合需要低延迟和高效传输的应用,如视频会议、实时游戏和语音通信等。
三、UDP输入输出
下图展示了一个应用进程写数据到UDP套接字中发生的步骤。

这一端的UDP简单地给来自用户的数据报安上它的8字节首部以构成UDP数据报,然后传递给IP层。
其中虚线框表示了套接字发送缓冲区,因为它实际并不存在。任何UDP套接字都有份发送缓冲区的大小,不过它仅仅是可写到该套接字的UDP数据报大小的上限。如果一个应用进程写一个大于套接字发送缓冲区大小的数据报,内核将返回进程一个EMSGSIZE错误。UDP是不可靠的,它不必保存应用进程数据的一个副本,因此不必像TCP一样有一个真正的发送缓冲区。
也就是说UDP没有真正意义上的发送缓冲区。调用sendto会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作。
UDP 的发送缓冲区在数据发送成功后,数据会立即从缓冲区中移除,不像 TCP 需要等待接收方的确认。
发送缓冲区(Send Buffer)是一个内核空间中的缓冲区,专门用于临时存储应用程序准备发送的数据。它的作用是在网络协议栈中不同层次之间传递数据时,确保数据能够有序且可靠地传输。
应用进程的数据在沿协议栈向下传递时,通常被复制到某种格式的一个内核缓冲区中。当数据通过协议栈传递并成功发送后,数据链路层完成了数据的传输任务,此时该数据的副本在发送缓冲区中的存在已经没有意义。因此,内核会将发送缓冲区中的数据副本丢弃,以便释放内存资源给后续需要发送的数据。
简单来说,发送缓冲区存在的意义就是:接收方来不及接收了,我们暂时把它放在缓冲区保存,等对方来得及接收了,有接收能力了再发送给对方。
UDP套接字的接收缓冲区:由UDP给某个特定套接字排队的UDP数据报的数目受限于该套接字接收缓冲区的大小,但是这个缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致。如果缓冲区满了,再到达的UDP数据就会被丢弃。
UDP没有发送缓冲区:
- UDP是一种无连接的协议,它不提供可靠的数据传输保证。当应用程序调用
sendto函数发送数据时,UDP协议会将数据直接传递给网络层,而不像TCP那样在发送缓冲区中排队等待确认。 - 由于UDP不进行拥塞控制,也没有重传机制,因此发送操作通常是立即返回的,即使数据报可能还没有被完全发送到网络上。
UDP的接收缓冲区:
- UDP的接收缓冲区存在于内核中,用于暂存从网络层接收到的UDP数据报。
- 由于UDP协议的性质,接收缓冲区不能保证数据报的顺序与发送顺序一致。数据报可能会因为网络延迟、路由差异等原因而以不同的顺序到达。
- 如果接收缓冲区满了,新到达的数据报可能会被丢弃。UDP协议本身不会通知发送方数据报丢失,因此需要应用程序自行处理这种情况。
应用注意事项:
- 应用程序在使用UDP时应该考虑到数据报可能会丢失、重复或乱序。
- 对于需要可靠传输的应用,开发者需要在应用层实现额外的机制,如确认、重传等。
- 应用程序还应该考虑到接收缓冲区的大小,以避免在高速网络环境中因为缓冲区溢出而丢失数据。
UDP不是全双工的,但是可以实现全双工。
UDP的设计目标是简单和低开销。全双工通信需要更多的控制信息和状态维护,这会增加复杂性,与UDP的设计目标相违背。全双工通信通常需要保持一定程度的连接状态。
全双工通信需要处理诸如流量控制、拥塞控制和数据包顺序等问题,UDP将这些责任交给了应用程序,自己则保持简单,只提供数据报文的发送和接收功能。如果UDP是全双工的,那么它需要在网络堆栈中为每个通信对维护更多的资源,例如缓冲区和状态信息。UDP的设计意图是尽量减少这种资源的使用。
注:UDP协议中使用connect会改变原来套接字绑定的目标地址和端口号,用新绑定的地址和端口号代替,原有的绑定状态会消失。与TCP不同,UDP的connect调用不会与目标地址进行任何形式的握手或建立连接。它仅仅是在套接字上设置了一个默认的目的地址。
UDP服务器接收数据的方式,以及是否能够同时接收来自多个客户端的数据
UDP是一种无连接的协议,它不保证数据的可靠传输,也不要求在数据传输之前建立连接。
接收数据的情况:
- 服务器使用
recvfrom系统调用等待接收数据。 recvfrom会阻塞当前线程,直到接收到客户端发送的数据。- 一旦接收到数据,服务器就会记录日志,并将接收到的数据处理后发送回客户端。
UDP协议支持多播和广播,这也是其能够同时接收来自多个客户端的原因之一:
- 广播:通过广播,服务器可以在本地网络中向所有客户端发送数据,所有客户端也可以通过广播向服务器发送消息。
- 多播:多播允许服务器订阅一个特定的多播组,然后任何加入这个组的客户端都可以向该组发送消息,服务器接收来自组内所有客户端的数据。
这种能力意味着UDP不仅可以通过单播与多个客户端通信,也可以通过广播和多播机制同时处理来自多个客户端的数据报。关于多个客户端同时发送数据:
- 由于UDP是无连接的,服务器不需要为每个客户端维持一个单独的连接,因此服务器可以同时处理来自多个客户端的数据。无论有多少客户端向同一个服务器地址发送数据包,服务器都可以使用相同的
recvfrom()函数接收来自不同客户端的数据包。 - 当服务器调用
recvfrom时,如果多个客户端几乎同时发送数据,操作系统内核的网络栈会处理这些数据报。也可能会接收到来自不同客户端的数据,这取决于内核调度和网络状况。
因此,UDP服务器能够由多个客户端同时发送数据,而不会像TCP那样需要为每个客户端建立一个独立的连接。
注意点:
- 由于UDP不保证数据的可靠传输,如果网络状况不佳或者数据报丢失,服务器可能不会收到某些客户端发送的数据。
recvfrom每次调用只处理一个数据报,如果多个数据报同时到达,它们会在内核中的队列中排队等待处理。
也就是说,UDP服务器能够同时接收来自多个客户端的数据,因为UDP协议本身支持多播和广播,并且在单个套接字上可以接收来自不同发送者的数据报。
四、UDP网络编程
UDP协议的服务器端程序设计的流程分为套接字建立、套接字于地址进行绑定、收发数据、关闭套接字等过程,分别对应函数socket、bind 、sendto 、recvfrom和close。

服务器端:建立套接字过程使用 socket 函数,建立的套接字类型为数据报套接字。地址结构与套接字文件描述符进行绑定。当绑定操作成功后,可以调用recvfrom函数从建立的套接字接收数据或者调用 sendto函数向建立的套接字发送络数据。当相关的处理过程结束后,调用 close函数关闭套接字。
- 创建UDP套接字得到套接字描述符
- 设置服务器地址和侦听端口
- 绑定套接字到侦听端口
- 接收客户端发送的数据
- 处理接收到的数据
- 发送响应给客户端
- 关闭套接字
客户端:套接字建立、收发数据、关闭套接字等过程,分别对应于函数 socket 、sendto 、recvfrom 和 close。建立套接字过程使用 socket函数。建立套接字之后,可以调用函数sendto向建立的套接字发送数据或者调用 recvfrom 函数从建立的套接字收网络数据。当相关的处理过程结束后,调用 close函数关闭套接字。
- 创建UDP套接字
- 设置服务器地址和端口
- 发送数据到服务器
- 接收服务器的响应
- 关闭套接字
UDP服务器可以在使用单个进程的情况下处理所有客户。对于UDP套接字,UDP层隐含有排队发生,即每个UDP套接字都有一个接送缓冲区,到达该套接字的每个数据报都进入这个套接字接收缓冲区。这样,在进程能够读该套接字中任何已排好队的数据报之前,如果有多个数据到达该套接字,那么相继到达的数据报仅仅加到该套接字的接收缓冲区中。然而这个缓冲区的大小是有限的。

上图中仅有一个服务器进程,它仅有的单个套接字用于接收所有到达的数据报并返回所有的响应。该套接字只有一个缓冲区来存放所到达的数据报。
如果一个客户数据报丢失,客户端将永远阻塞在recvfrom调用处,等待一个永远收不到的服务器应答。防止这种永久阻塞的方法一般是客户的recvfrom调用设置一个超时。
客户端必须给sendto调用指定服务器的端口号和IP地址。一般来说,客户端的IP地址和端口号都是由内核自动选择。即客户端不需要调用bind。客户端的IP地址却可以随客户发送的每一个UDP数据报而变动。

如果客户主机是多宿的(即具有多个网络接口和多个IP地址),那么在发送UDP数据报时,客户有可能在两个目的地之间交替选择。默认情况下,如果未明确指定,则操作系统会选择默认的发送接口,这通常是系统的路由表决定的。
号和IP地址。一般来说,客户端的IP地址和端口号都是由内核自动选择。即客户端不需要调用bind。客户端的IP地址却可以随客户发送的每一个UDP数据报而变动。

如果客户主机是多宿的(即具有多个网络接口和多个IP地址),那么在发送UDP数据报时,客户有可能在两个目的地之间交替选择。默认情况下,如果未明确指定,则操作系统会选择默认的发送接口,这通常是系统的路由表决定的。
相关文章:
【计算机网络】UDP 协议详解及其网络编程应用
文章目录 一、引言二、UDP1、UDP的协议格式2、UDP 报文的解包和分用3、UDP面向数据报的特点 三、UDP输入输出四、UDP网络编程 一、引言 UDP(User Datagram Protocol,用户数据报协议)是一种网络通信协议,它属于传输层的协议。是一…...
基于ESP32S3的链接大语言模型对话模块
本实物模块从实物外观、模块组成、API申请及功能说明四部分来介绍这款基于ESP32S3的大语言模型对话模块。 1、实物外观 2、模块介绍 本硬件平台主要由三个模块组成,包括MAX9814录音模块、MAX98357音频功放模块和ESP32S3模块。如下图所示。 MAX9814录音模块&#…...
Cpp输出多字符常量警告
Cpp输出多字符常量警告 Cpp中用单引号(single quotes)表示单个字符(single character),例如a,$,用双引号(double quotes)表示字符串文本(text),例如"Hello World! " 当在一个单引号里面存在多个字符时,Cpp…...
Maven从入门到精通(二)
一、什么是pom.xml pom.xml是Maven项目的核心配置文件,它是 项目对象模型 - Project Object Model(POM)的缩写。POM定义了项目的所有属性,包括项目的名称、版本、依赖关系、构建配置等。使用pom.xml,我们可以轻松地管…...
【Kubernetes】常见面试题汇总(二十四)
目录 71.假设一家公司想要修改它的部署方法,并希望建立一个更具可扩展性和响应性的平台。您如何看待这家公司能够实现这一目标以满足客户需求? 72.考虑一家拥有非常分散的系统的跨国公司,期待解决整体代码库问题。您认为公司如何解决他们的问…...
最低成本的游戏串流方案分享 如何自己打造云电脑?
今天教大家如何最低成本实现串流 出门在外也可以随时随地游玩端游大作 硬件准备:一台电脑 手机/平板一台 软件:Gameviewer远程 为啥不用moonlight等其他软件呢 因为设置公网穿透等复杂操作对小白来说不太友好 而GameViewer从安装到使用仅需一键 对比同类…...
python运行时错误:找不到fbgemm.dll
python运行时错误:找不到fbgemm.dll 报错: OSError: [WinError 126] 找不到指定的模块。 Error loading "D:\program\py\312\Lib\site-packages\torch\lib\fbgemm.dll" or one of its dependencies. 原因是Windows下缺失:libomp140…...
给虚拟机linux系统安装交叉编译工具链
我们在电脑上写的代码编译生成的是X86架构的二进制文件,只能在X86平台上运行,而开发板是ARM架构因此需要安装交叉编译链工具,这样在电脑上写的代码交叉编译之后生成的是ARM架构的二进制文件。 绿色的字眼是与本文无关的只是这样有助于我们的…...
Redhat 7,8系(复刻系列) 一键部署Oracle21c-xe rpm
Oracle21c-xe前言 无论您是开发人员、DBA、数据科学家、教育工作者,还是仅仅对数据库感兴趣,Oracle Database Express Edition (XE) 都是理想的入门方式。它是全球企业可依赖的强大的 Oracle Database,提供简单的下载、易于使用和功能齐全的体验。您可以在任何环境中使用该…...
Web植物管理系统-下位机部分
本节主要展示上位机部分,采用BSP编程,不附带BSP中各个头文件的说明,仅仅是对main逻辑进行解释 main.c 上下位机通信 通过串口通信,有两位数据验证头(verify数组中保存对应的数据头 0xAA55) 通信格式 上位发送11字节…...
leetcode169. 多数元素
给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入:nums [3,2,3] 输出:3 示例…...
从大脑图谱/ROI中提取BOLD信号
动机 在功能连接(Functional Connectivity,FC)构建过程中,由于FC中元素数目是节点数目的平方关系,所以在计算FC之前进行数据降维是一个常见的选择。 一般会将体素级/顶点级BOLD信号(在2mm的图像分辨率下大脑…...
Java-数据结构-优先级队列(堆)-(一) (;´д`)ゞ
文本目录: ❄️一、优先级队列: ➷ 1、概念: ❄️二、优先级队列的模拟实现: ➷ 1、堆的概念: ➷ 2、堆的性质: ➷ 3、堆的创建: ▶ 向下调整: ➷ 4、堆的插入和删除: …...
工厂模式(二):工厂方法模式
一、概念 工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。从而使得系统更加灵活。客户端可以通过调用工厂方法来创建所需的产品,而不必…...
【洛谷】P11036 【MX-X3-T3】「RiOI-4」GCD 与 LCM 问题 的题解
【洛谷】P11036 【MX-X3-T3】「RiOI-4」GCD 与 LCM 问题 的题解 题目传送门 题解 神奇构造题qaq 简化一下下题目,就是要求 a b c d gcd ( a , b ) lcm ( c , d ) a b c d \gcd(a, b) \operatorname{lcm}(c,d) abcdgcd(a,b)lcm(c,d) 分类讨论 …...
MyBatis系统学习(三)——动态SQL
MyBatis 是一款优秀的持久层框架,它通过 XML 或注解方式将 SQL 语句与 Java 对象映射起来。动态 SQL 是 MyBatis 中非常强大的功能之一,能够根据不同的条件动态生成 SQL 语句。动态 SQL 通过各种标签来灵活生成 SQL,从而避免了在代码中拼接 S…...
get_property --Cmakelist之中
get_property 是 CMake 中用于获取目标、目录、变量或文件等属性的命令。它可以提取某个特定属性的值,以便在构建脚本的其他地方使用。 语法 get_property(<variable> <TYPE> <name> PROPERTY <property-name> [SET | DEFINED | BRIEF_DO…...
【Redis】Redis 典型应用 - 分布式锁原理与实现
目录 Redis 典型应⽤ - 分布式锁什么是分布式锁分布式锁的基础实现引⼊过期时间引⼊校验 id引⼊ lua引⼊ watch dog (看⻔狗)引⼊ Redlock 算法其他功能 Redis 典型应⽤ - 分布式锁 什么是分布式锁 在⼀个分布式的系统中, 也会涉及到多个节点访问同⼀个公共资源的…...
Pybind11的使用
目录 1. 引言1.1 Pybind11 简介1.2 为什么需要 Pybind11 2. 使用 Pybind11 进行 C 与 Python 交互2.1 基本用法2.2 编译与生成共享库2.2.1 在 Linux 下编译2.2.2 在 macOS 下编译2.2.3 编译选项详解 2.3 在 Python 中使用编译后的模块 3. 高级用法与注意事项3.1 绑定类和复杂数…...
鸿蒙-沉浸式pc端失效
咨询描述: 因PC北向窗口涉及沉浸式时,预计发生接口废弃导致不兼容变更,涉及接口setImmersiveModeEnabledState、setWindowLayoutFullSceen 如果应用支持沉浸式(窗口全屏且隐藏状态栏&标题栏&Dock栏)࿰…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
