南县建设局网站/网站维护工程师
UDP4
UDP4协议说明
UDP的全称是User Datagram Protocol,它不提供复杂的控制机制,仅利用IP提供面向无连接的通信服务。它将上层应用程序发来的数据在收到的那一刻,立即按照原样发送到网络。
UDP报文格式:
各个参数说明如下:
字段 | 长度(字节) | 描述 |
---|---|---|
Source Port | 2 | 发送端口,标识哪个应用程序发送(发送进程)。 |
Destination Port | 2 | 目标端口,标识哪个应用程序接收(接收进程)。 |
Length | 2 | UDP首部加上UDP数据的字节数,最小为8。 |
Checksum | 2 | 覆盖UDP首部和UDP数据,是可选的。 |
data octets | 变长 | UDP负载,可选的。 |
前面的四个参数对应到UEFI代码中就是UDP头部:
//
// UDP header definition
//
typedef struct {UINT16 SrcPort;UINT16 DstPort;UINT16 Length;UINT16 Checksum;
} EFI_UDP_HEADER;
UDP4代码综述
UDP4也是一个通用的网络协议,其实现在NetworkPkg\Udp4Dxe\Udp4Dxe.inf,这里首先需要看下它的入口:
EFI_STATUS
EFIAPI
Udp4DriverEntryPoint (IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable)
{//// Install the Udp4DriverBinding and Udp4ComponentName protocols.//Status = EfiLibInstallDriverBindingComponentName2 (ImageHandle,SystemTable,&gUdp4DriverBinding,ImageHandle,&gUdp4ComponentName,&gUdp4ComponentName2);if (!EFI_ERROR (Status)) {//// Initialize the UDP random port.//mUdp4RandomPort = (UINT16)(((UINT16)NetRandomInitSeed ()) % UDP4_PORT_KNOWN + UDP4_PORT_KNOWN); // 宏的值是1024}
}
因为UDP4也是一个UEFI Driver Model,所以第一步是安装gUdp4DriverBinding
,其实现:
EFI_DRIVER_BINDING_PROTOCOL gUdp4DriverBinding = {Udp4DriverBindingSupported,Udp4DriverBindingStart,Udp4DriverBindingStop,0xa,NULL,NULL
};
而第二步是初始化一个随机的UDP端口,根据通用网络协议的做法,UDP的端口占两个字节(即16位),只要不是0-1023里面的公认端口都可以,且跟TCP端口的一致也没有关系。
UDP4在UEFI网络协议栈中的关系图:
Udp4DriverBindingSupported
UDP4依赖于IP4:
EFI_STATUS
EFIAPI
Udp4DriverBindingSupported (IN EFI_DRIVER_BINDING_PROTOCOL *This,IN EFI_HANDLE ControllerHandle,IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
{//// Test for the Ip4 Protocol//Status = gBS->OpenProtocol (ControllerHandle,&gEfiIp4ServiceBindingProtocolGuid,NULL,This->DriverBindingHandle,ControllerHandle,EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
}
Udp4DriverBindingStart
Start函数的流程大致如下:
- 初始化
UDP4_SERVICE_DATA
。 - 安装
gEfiUdp4ServiceBindingProtocolGuid
。
同其它驱动一样,重点也是结构体,这里就是UDP4_SERVICE_DATA
。
UDP4_SERVICE_DATA
UDP4_SERVICE_DATA
在Start函数中创建:
EFI_STATUS
EFIAPI
Udp4DriverBindingStart (IN EFI_DRIVER_BINDING_PROTOCOL *This,IN EFI_HANDLE ControllerHandle,IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
{Status = Udp4CreateService (Udp4Service, This->DriverBindingHandle, ControllerHandle);
}
其结构体定义如下:
typedef struct _UDP4_SERVICE_DATA_ {UINT32 Signature;EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;EFI_HANDLE ImageHandle;EFI_HANDLE ControllerHandle;LIST_ENTRY ChildrenList;UINTN ChildrenNumber;IP_IO *IpIo;EFI_EVENT TimeoutEvent;
} UDP4_SERVICE_DATA;
相比之前的服务数据,这个结构体相当得简单,其中比较重要的成员有:
ServiceBinding
:对应mUdp4ServiceBinding
:
EFI_SERVICE_BINDING_PROTOCOL mUdp4ServiceBinding = {Udp4ServiceBindingCreateChild,Udp4ServiceBindingDestroyChild
};
用于创建UDP4子项。
ChildrenList
,ChildrenNumber
:对应UDP4_INSTANCE_DATA
结构体,由Udp4ServiceBindingCreateChild()
创建,是表示子项的结构体,在UDP4_INSTANCE_DATA会进一步介绍。IpIo
:它是对IP4实例的一个包装,UDP4通过它来进行通信,在IP_IO已经介绍过。在UDP4以及TCP4中会进场看到类似IP_IO
这样的结构体,它们仅仅是对IP层的保证,之所以要有这样的包装,是因为存在IPv4和IPv6两个版本,而这里只关注IPv4。TimeoutEvent
:一个定时事件,创建的位置是在Udp4CreateService()
函数中:
EFI_STATUS
Udp4CreateService (IN OUT UDP4_SERVICE_DATA *Udp4Service,IN EFI_HANDLE ImageHandle,IN EFI_HANDLE ControllerHandle)
{//// Create the event for Udp timeout checking.//Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL,TPL_CALLBACK,Udp4CheckTimeout,Udp4Service,&Udp4Service->TimeoutEvent);//// Start the timeout timer event.//Status = gBS->SetTimer (Udp4Service->TimeoutEvent,TimerPeriodic,UDP4_TIMEOUT_INTERVAL // 50 milliseconds);
对应的回调函数Udp4CheckTimeout()
,它用来检测接收到的报文是否过期,其主体代码:
VOID
EFIAPI
Udp4CheckTimeout (IN EFI_EVENT Event,IN VOID *Context)
{NET_LIST_FOR_EACH (Entry, &Udp4Service->ChildrenList) {//// Iterate all the instances belonging to this service context.//Instance = NET_LIST_USER_STRUCT (Entry, UDP4_INSTANCE_DATA, Link);NET_CHECK_SIGNATURE (Instance, UDP4_INSTANCE_DATA_SIGNATURE);if (!Instance->Configured || (Instance->ConfigData.ReceiveTimeout == 0)) {//// Skip this instance if it's not configured or no receive timeout.//continue;}NET_LIST_FOR_EACH_SAFE (WrapEntry, NextEntry, &Instance->RcvdDgramQue) {//// Iterate all the rxdatas belonging to this udp instance.//Wrap = NET_LIST_USER_STRUCT (WrapEntry, UDP4_RXDATA_WRAP, Link);//// TimeoutTick unit is microsecond, MNP_TIMEOUT_CHECK_INTERVAL unit is 100ns.//if (Wrap->TimeoutTick < (UDP4_TIMEOUT_INTERVAL / 10)) {//// Remove this RxData if it timeouts.//Udp4RecycleRxDataWrap (NULL, (VOID *)Wrap);} else {Wrap->TimeoutTick -= (UDP4_TIMEOUT_INTERVAL / 10);}}}
}
这里的Wrap
对应结构体UDP4_RXDATA_WRAP
:
typedef struct _UDP4_RXDATA_WRAP_ {LIST_ENTRY Link;NET_BUF *Packet;UINT32 TimeoutTick;EFI_UDP4_RECEIVE_DATA RxData;
} UDP4_RXDATA_WRAP;
它通过Udp4WrapRxData()
创建,然后放到一个队列中供UDP驱动处理,如果来不及处理就会过期,而过期时间也由这里的成员TimeoutTick
指定,而该成员由另外的一个值指定:
Wrap->TimeoutTick = Instance->ConfigData.ReceiveTimeout;
Instance
是后面会介绍的UDP4_INSTANCE_DATA
中的配置参数ConfigData
,ConfigData.ReceiveTimeout
的值在创建时是-1,表示不会过期:
//// use the -1 magic number to disable the receiving process of the ip instance.//Ip4ConfigData->ReceiveTimeout = (UINT32)(-1);
不过在UDP4的配置中可以修改:
EFI_STATUS
EFIAPI
Udp4Configure (IN EFI_UDP4_PROTOCOL *This,IN EFI_UDP4_CONFIG_DATA *UdpConfigData OPTIONAL)
{if (UdpConfigData != NULL) {if (Instance->Configured) {//// Save the reconfigurable parameters.//Instance->ConfigData.TransmitTimeout = UdpConfigData->TransmitTimeout;}}
}
UDP4_INSTANCE_DATA
UDP4_INSTANCE_DATA
表示一个UDP4子项,其它位于NetworkPkg\Udp4Dxe\Udp4Impl.h:
typedef struct _UDP4_INSTANCE_DATA_ {UINT32 Signature;LIST_ENTRY Link;UDP4_SERVICE_DATA *Udp4Service;EFI_UDP4_PROTOCOL Udp4Proto;EFI_UDP4_CONFIG_DATA ConfigData;EFI_HANDLE ChildHandle;BOOLEAN Configured;BOOLEAN IsNoMapping;NET_MAP TxTokens;NET_MAP RxTokens;NET_MAP McastIps;LIST_ENTRY RcvdDgramQue;LIST_ENTRY DeliveredDgramQue;UINT16 HeadSum;EFI_STATUS IcmpError;IP_IO_IP_INFO *IpInfo;BOOLEAN InDestroy;
} UDP4_INSTANCE_DATA;
下面介绍其中比较重要的成员:
-
Udp4Service
:指向UDP4服务的结构体。 -
Udp4Proto
:对应EFI_UDP4_PROTOCOL,后面会进一步介绍。 -
ConfigData
:UDP配置数据:
typedef struct {//// Receiving Filters//BOOLEAN AcceptBroadcast;BOOLEAN AcceptPromiscuous;BOOLEAN AcceptAnyPort;BOOLEAN AllowDuplicatePort;//// I/O parameters//UINT8 TypeOfService;UINT8 TimeToLive;BOOLEAN DoNotFragment;UINT32 ReceiveTimeout;UINT32 TransmitTimeout;//// Access Point//BOOLEAN UseDefaultAddress;EFI_IPv4_ADDRESS StationAddress;EFI_IPv4_ADDRESS SubnetMask;UINT16 StationPort;EFI_IPv4_ADDRESS RemoteAddress;UINT16 RemotePort;
} EFI_UDP4_CONFIG_DATA;
TxTokens
、RxTokens
:描述收发数据的映射:
typedef struct {LIST_ENTRY Used;LIST_ENTRY Recycled;UINTN Count;
} NET_MAP;
真正的Token是EFI_UDP4_COMPLETION_TOKEN
:
typedef struct {EFI_EVENT Event;EFI_STATUS Status;union {EFI_UDP4_RECEIVE_DATA *RxData;EFI_UDP4_TRANSMIT_DATA *TxData;} Packet;
} EFI_UDP4_COMPLETION_TOKEN;
RcvdDgramQue
、DeliveredDgramQue
:处理收发数据的队列。IpInfo
:底层IP4实例需要使用到的结构体:
///
/// The IP_IO_IP_INFO is used in IpIoSend() to override the default IP instance
/// in IP_IO.
///
typedef struct _IP_IO_IP_INFO {EFI_IP_ADDRESS Addr;IP_IO_IP_MASK PreMask;LIST_ENTRY Entry;EFI_HANDLE ChildHandle;IP_IO_IP_PROTOCOL Ip;IP_IO_IP_COMPLETION_TOKEN DummyRcvToken;INTN RefCnt;UINT8 IpVersion;
} IP_IO_IP_INFO;
从注释中可以看到发送数据时会使用到。
EFI_UDP4_PROTOCOL
UDP4通信的接口,该Protocol的结构体如下:
///
/// The EFI_UDP4_PROTOCOL defines an EFI UDPv4 Protocol session that can be used
/// by any network drivers, applications, or daemons to transmit or receive UDP packets.
/// This protocol instance can either be bound to a specified port as a service or
/// connected to some remote peer as an active client. Each instance has its own settings,
/// such as the routing table and group table, which are independent from each other.
///
struct _EFI_UDP4_PROTOCOL {EFI_UDP4_GET_MODE_DATA GetModeData;EFI_UDP4_CONFIGURE Configure;EFI_UDP4_GROUPS Groups;EFI_UDP4_ROUTES Routes;EFI_UDP4_TRANSMIT Transmit;EFI_UDP4_RECEIVE Receive;EFI_UDP4_CANCEL Cancel;EFI_UDP4_POLL Poll;
};
对应的实现:
EFI_UDP4_PROTOCOL mUdp4Protocol = {Udp4GetModeData,Udp4Configure,Udp4Groups,Udp4Routes,Udp4Transmit,Udp4Receive,Udp4Cancel,Udp4Poll
};
后面会介绍这些函数的实现。
Udp4.GetModeData
对应的实现是Udp4GetModeData()
,其代码实现:
EFI_STATUS
EFIAPI
Udp4GetModeData (IN EFI_UDP4_PROTOCOL *This,OUT EFI_UDP4_CONFIG_DATA *Udp4ConfigData OPTIONAL,OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL,OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL)
{if (Udp4ConfigData != NULL) {//// Set the Udp4ConfigData.//CopyMem (Udp4ConfigData, &Instance->ConfigData, sizeof (*Udp4ConfigData));}Ip = Instance->IpInfo->Ip.Ip4;//// Get the underlying Ip4ModeData, MnpConfigData and SnpModeData.//Status = Ip->GetModeData (Ip, Ip4ModeData, MnpConfigData, SnpModeData);}
从这里可以看出,上层的网络协议可以获取到下层所有的模式数据。
对于UDP4来说,数据在UDP4_INSTANCE_DATA
的ConfigData
成员中。
Udp4.Configure
对应的实现是Udp4Configure()
,其代码实现:
EFI_STATUS
EFIAPI
Udp4Configure (IN EFI_UDP4_PROTOCOL *This,IN EFI_UDP4_CONFIG_DATA *UdpConfigData OPTIONAL)
{// 根据是否有配置存在两种情况,没有数据相当于重置if (UdpConfigData != NULL) {if (Instance->Configured) {//// The instance is already configured, try to do the re-configuration.//if (!Udp4IsReconfigurable (&Instance->ConfigData, UdpConfigData)) {//// If the new configuration data wants to change some unreconfigurable// settings, return EFI_ALREADY_STARTED.//Status = EFI_ALREADY_STARTED;goto ON_EXIT;}//// Save the reconfigurable parameters.//Instance->ConfigData.TypeOfService = UdpConfigData->TypeOfService;Instance->ConfigData.TimeToLive = UdpConfigData->TimeToLive;Instance->ConfigData.DoNotFragment = UdpConfigData->DoNotFragment;Instance->ConfigData.ReceiveTimeout = UdpConfigData->ReceiveTimeout;Instance->ConfigData.TransmitTimeout = UdpConfigData->TransmitTimeout;} else {//// Construct the Ip configuration data from the UdpConfigData.//Udp4BuildIp4ConfigData (UdpConfigData, &Ip4ConfigData);//// Configure the Ip instance wrapped in the IpInfo.//Status = IpIoConfigIp (Instance->IpInfo, &Ip4ConfigData);if (EFI_ERROR (Status)) {if (Status == EFI_NO_MAPPING) {Instance->IsNoMapping = TRUE;}goto ON_EXIT;}Instance->IsNoMapping = FALSE;//// Save the configuration data.//CopyMem (&Instance->ConfigData, UdpConfigData, sizeof (Instance->ConfigData));IP4_COPY_ADDRESS (&Instance->ConfigData.StationAddress, &Ip4ConfigData.StationAddress);IP4_COPY_ADDRESS (&Instance->ConfigData.SubnetMask, &Ip4ConfigData.SubnetMask);//// Try to allocate the required port resource.//Status = Udp4Bind (&Udp4Service->ChildrenList, &Instance->ConfigData);if (EFI_ERROR (Status)) {//// Reset the ip instance if bind fails.//IpIoConfigIp (Instance->IpInfo, NULL);goto ON_EXIT;}//// Pre calculate the checksum for the pseudo head, ignore the UDP length first.//CopyMem (&LocalAddr, &Instance->ConfigData.StationAddress, sizeof (IP4_ADDR));CopyMem (&RemoteAddr, &Instance->ConfigData.RemoteAddress, sizeof (IP4_ADDR));Instance->HeadSum = NetPseudoHeadChecksum (LocalAddr,RemoteAddr,EFI_IP_PROTO_UDP,0);Instance->Configured = TRUE;}} else {//// UdpConfigData is NULL, reset the instance.//Instance->Configured = FALSE;Instance->IsNoMapping = FALSE;//// Reset the Ip instance wrapped in the IpInfo.//IpIoConfigIp (Instance->IpInfo, NULL);//// Cancel all the user tokens.//Instance->Udp4Proto.Cancel (&Instance->Udp4Proto, NULL);//// Remove the buffered RxData for this instance.//Udp4FlushRcvdDgram (Instance);}
}
根据输入参数的不同,以及是否已经配置过,会走到不同的流程,此外,UDP4还会配置进一步调用IP4的接口进行配置。
Udp4.Transmit
对应的实现是Udp4Transmit()
,其代码实现:
EFI_STATUS
EFIAPI
Udp4Transmit (IN EFI_UDP4_PROTOCOL *This,IN EFI_UDP4_COMPLETION_TOKEN *Token)
{//// Validate the Token, if the token is invalid return the error code.//Status = Udp4ValidateTxToken (Instance, Token);if (EFI_ERROR (Status)) {goto ON_EXIT;}if (EFI_ERROR (NetMapIterate (&Instance->TxTokens, Udp4TokenExist, Token)) ||EFI_ERROR (NetMapIterate (&Instance->RxTokens, Udp4TokenExist, Token))){//// Try to find a duplicate token in the two token maps, if found, return// EFI_ACCESS_DENIED.//Status = EFI_ACCESS_DENIED;goto ON_EXIT;}TxData = Token->Packet.TxData;//// Create a net buffer to hold the user buffer and the udp header.//Packet = NetbufFromExt ((NET_FRAGMENT *)TxData->FragmentTable,TxData->FragmentCount,UDP4_HEADER_SIZE,0,Udp4NetVectorExtFree,NULL);if (Packet == NULL) {Status = EFI_OUT_OF_RESOURCES;goto ON_EXIT;}//// Store the IpIo in ProtoData.//Udp4Service = Instance->Udp4Service;*((UINTN *)&Packet->ProtoData[0]) = (UINTN)(Udp4Service->IpIo);Udp4Header = (EFI_UDP_HEADER *)NetbufAllocSpace (Packet, UDP4_HEADER_SIZE, TRUE);ASSERT (Udp4Header != NULL);ConfigData = &Instance->ConfigData;//// Fill the udp header.//Udp4Header->SrcPort = HTONS (ConfigData->StationPort);Udp4Header->DstPort = HTONS (ConfigData->RemotePort);Udp4Header->Length = HTONS ((UINT16)Packet->TotalSize);Udp4Header->Checksum = 0;UdpSessionData = TxData->UdpSessionData;IP4_COPY_ADDRESS (&Override.Ip4OverrideData.SourceAddress, &ConfigData->StationAddress);if (UdpSessionData != NULL) {//// Set the SourceAddress, SrcPort and Destination according to the specified// UdpSessionData.//if (!EFI_IP4_EQUAL (&UdpSessionData->SourceAddress, &mZeroIp4Addr)) {IP4_COPY_ADDRESS (&Override.Ip4OverrideData.SourceAddress, &UdpSessionData->SourceAddress);}if (UdpSessionData->SourcePort != 0) {Udp4Header->SrcPort = HTONS (UdpSessionData->SourcePort);}if (UdpSessionData->DestinationPort != 0) {Udp4Header->DstPort = HTONS (UdpSessionData->DestinationPort);}CopyMem (&Source, &Override.Ip4OverrideData.SourceAddress, sizeof (IP4_ADDR));CopyMem (&Destination, &UdpSessionData->DestinationAddress, sizeof (IP4_ADDR));//// calculate the pseudo head checksum using the overridden parameters.//HeadSum = NetPseudoHeadChecksum (Source,Destination,EFI_IP_PROTO_UDP,0);} else {//// UdpSessionData is NULL, use the address and port information previously configured.//CopyMem (&Destination, &ConfigData->RemoteAddress, sizeof (IP4_ADDR));HeadSum = Instance->HeadSum;}//// calculate the checksum.//Udp4Header->Checksum = Udp4Checksum (Packet, HeadSum);if (Udp4Header->Checksum == 0) {//// If the calculated checksum is 0, fill the Checksum field with all ones.//Udp4Header->Checksum = 0xffff;}//// Fill the IpIo Override data.//if (TxData->GatewayAddress != NULL) {IP4_COPY_ADDRESS (&Override.Ip4OverrideData.GatewayAddress, TxData->GatewayAddress);} else {ZeroMem (&Override.Ip4OverrideData.GatewayAddress, sizeof (EFI_IPv4_ADDRESS));}Override.Ip4OverrideData.Protocol = EFI_IP_PROTO_UDP;Override.Ip4OverrideData.TypeOfService = ConfigData->TypeOfService;Override.Ip4OverrideData.TimeToLive = ConfigData->TimeToLive;Override.Ip4OverrideData.DoNotFragment = ConfigData->DoNotFragment;//// Save the token into the TxToken map.//Status = NetMapInsertTail (&Instance->TxTokens, Token, Packet);//// Send out this datagram through IpIo.//IpDestAddr.Addr[0] = Destination;Status = IpIoSend (Udp4Service->IpIo,Packet,Instance->IpInfo,Instance,Token,&IpDestAddr,&Override);
}
Udp4.Receive
对应的实现是Udp4Receive()
,其代码实现:
EFI_STATUS
EFIAPI
Udp4Receive (IN EFI_UDP4_PROTOCOL *This,IN EFI_UDP4_COMPLETION_TOKEN *Token)
{if (EFI_ERROR (NetMapIterate (&Instance->RxTokens, Udp4TokenExist, Token)) ||EFI_ERROR (NetMapIterate (&Instance->TxTokens, Udp4TokenExist, Token))){//// Return EFI_ACCESS_DENIED if the specified token is already in the TxTokens or// RxTokens map.//Status = EFI_ACCESS_DENIED;goto ON_EXIT;}Token->Packet.RxData = NULL;//// Save the token into the RxTokens map.//Status = NetMapInsertTail (&Instance->RxTokens, Token, NULL);if (EFI_ERROR (Status)) {Status = EFI_NOT_READY;goto ON_EXIT;}//// If there is an icmp error, report it.//Udp4ReportIcmpError (Instance);//// Try to deliver the received datagrams.//Udp4InstanceDeliverDgram (Instance);//// Dispatch the DPC queued by the NotifyFunction of Token->Event.//DispatchDpc ();
}
同其它的网络协议中的Receive一样,重点是注册Token。
Udp4.Poll
对应的实现是Udp4Poll()
,其代码实现就是调用下一层的Poll:
EFI_STATUS
EFIAPI
Udp4Poll (IN EFI_UDP4_PROTOCOL *This)
{Ip = Instance->IpInfo->Ip.Ip4;//// Invode the Ip instance consumed by the udp instance to do the poll operation.//return Ip->Poll (Ip);
}
代码示例
DHCP和DNS等都是使用UDP的,后面会进一步说明。
相关文章:

【UEFI基础】EDK网络框架(UDP4)
UDP4 UDP4协议说明 UDP的全称是User Datagram Protocol,它不提供复杂的控制机制,仅利用IP提供面向无连接的通信服务。它将上层应用程序发来的数据在收到的那一刻,立即按照原样发送到网络。 UDP报文格式: 各个参数说明如下&…...

vivado使用注意事项
记得给constrs(.xdc)限制文件设置为目标文件(set as Target Consraint File)...

gin路由篇
1. 基本路由 gin 框架中采用的路由库是基于httprouter做的 import ("net/http""github.com/gin-gonic/gin" )func main() {// 1.创建路由r : gin.Default()// 2.绑定路由规则,执行的函数// gin.Context,封装了request和responser.…...

C++逆向分析--继承的本质
一.一些思考 继承是面向对象的三个特性之一。这篇文章我们从底层的角度去理解什么是继承。他的作用是什么。首先继承的出现是更好的避免代码的重复冗余。要理解一件事很重要,C其实是C的延申。那么C的出现是为了解决C语言上C祖师爷认为不友好的事情,也为…...

LeetCode解法汇总2865. 美丽塔 I
目录链接: 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目: https://github.com/September26/java-algorithms 原题链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 描述: 给你一个长…...

pinia 的使用方法
使用方式(选项式) 1、在 mian.js 导入 pinia 里的 createPinia 函数。 2、app.use 这个 createPinia 函数的返回值。 // main.jsimport { createPinia } from pinia;app.use(createPinia()); 3、创建一个 js 文件(该文件保存着共享的数据&…...

sky_take_out
day01: 前端网址通过nginx访问后端网址(前后网址不一致),有三个好处: 一是提高访问速度,二是进行负载均衡,三是保障后端安全性 用md5加密了密码 后端使用knife4j调试,用Swagger生成接口文档&am…...

LC 2865. 美丽塔 I
2865. 美丽塔 I 难度 : 中等 题目大意 给你一个长度为 n 下标从 0 开始的整数数组 maxHeights 。 你的任务是在坐标轴上建 n 座塔。第 i 座塔的下标为 i ,高度为 heights[i] 。 如果以下条件满足,我们称这些塔是 美丽 的: 1 < heights…...

代理设计模式JDK动态代理CGLIB动态代理原理
代理设计模式 代理模式(Proxy),为其它对象提供一种代理以控制对这个对象的访问。如下图 从上面的类图可以看出,通过代理模式,客户端访问接口时的实例实际上是Proxy对象,Proxy对象持有RealSubject的引用&am…...

[陇剑杯 2021]webshell
[陇剑杯 2021]webshell 题目做法及思路解析(个人分享) 问一:单位网站被黑客挂马,请您从流量中分析出webshell,进行回答: 黑客登录系统使用的密码是_____________。 题目思路: 分析题目&…...

美易官方:小米汽车交付时间传闻被官方辟谣
在科技与互联网的快速发展浪潮中,各类信息传播速度之快令人咋舌。然而,信息的真实性却时常成为公众关注的焦点。近日,关于小米汽车交付时间的谣言再次引起市场的广泛关注。小米公司发言人迅速作出回应,明确指出这些关于小米汽车交…...

MySQL 简介
什么是MySQL?(熟悉) MySQL是一个开源的、使用标准SQL语言的、可运行于多个系统的、支持多语言的、支持大型数据库的关系型数据库管理系统。由瑞典 MySQL AB 公司开发,目前属于 Oracle 旗下产品。我们通常使用关系型数据库管理系统…...

动态规划最后一天(回文串)
目录 647. 回文子串 看到题目的第一想法 看到代码随想录之后的想法 自己实现过程中遇到的困难(看代码) 516.最长回文子序列 看到题目的第一想法 看到代码随想录之后的想法 自己实现过程中遇到的困难(看代码) 647. 回文子串 力扣题目链接…...

c语言之scanf函数
scanf函数语法格式与printf函数很相似,语法是scanf(格式控制,地址列表)组成 其中格式控制分为两部分,一部分由双引号括起来的,%和格式字符组成的格式字符串 普通字符串则是原样输出 地址列表是若干地址组成的表列,可以是变量的…...

ORM-02-JPA Java Persistence API 注解入门介绍
拓展阅读 The jdbc pool for java.(java 手写 jdbc 数据库连接池实现) The simple mybatis.(手写简易版 mybatis) JPA JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射…...

【MQ01】什么是消息队列?用哪个消息队列?
什么是消息队列?用哪个消息队列? 来了来了,消息队列系列总算来咯。对于搜索引擎相关的知识大家消化的怎么样呀?其实对于搜索引擎来说,我们学习的内容还是挺全面的,也算是比较深入了。而对于消息队列来说&am…...

2023年度AI盘点 AIGC|AGI|ChatGPT|人工智能大模型
前言 「作者主页」:雪碧有白泡泡 「个人网站」:雪碧的个人网站 2023年是人工智能大语言模型大爆发的一年,一些概念和英文缩写也在这一年里集中出现,很容易混淆,甚至把人搞懵。 文章目录 前言01 《ChatGPT 驱动软件开…...

【Flink-CDC】Flink CDC 介绍和原理概述
【Flink-CDC】Flink CDC 介绍和原理概述 1)基于查询的 CDC 和基于日志的 CDC2)Flink CDC3)Flink CDC原理简述4)基于 Flink SQL CDC 的数据同步方案实践4.1.案例 1 : Flink SQL CDC JDBC Connector4.2.案例 2 : CDC Streaming ETL…...

长城资产信息技术岗24届校招面试面经
本文介绍2024届秋招中,中国长城资产管理股份有限公司的信息技术岗岗位一面的面试基本情况、提问问题等。 10月投递了中国长城资产管理股份有限公司的信息技术岗岗位,所在部门为长城新盛信托有限责任公司。目前完成了一面,在这里记录一下一面经…...

【计算机网络】TCP握手与挥手:三步奏和四步曲
这里写目录标题 前言三次握手四次挥手三次握手和四次挥手的作用TCP三次握手的作用建立连接防止已失效的连接请求建立连接防止重复连接 TCP四次挥手的作用:安全关闭连接避免数据丢失避免半开连接 总结: 总结 前言 TCP(传输控制协议)…...

设计模式学习总结
责任链模式 使用方法: 1.创建接口 2.定义实现类,每个实现类实现接口,并拥有一个ArchiveHandle的成员,用作责任链的链接 public interface ArchiveHandle {void handle(ArchiveVO archiveVO); } public class ArchivePreHandle i…...

「HDLBits题解」Cellular automata
本专栏的目的是分享可以通过HDLBits仿真的Verilog代码 以提供参考 各位可同时参考我的代码和官方题解代码 或许会有所收益 题目链接:Rule90 - HDLBits module top_module(input clk,input load,input [511:0] data,output [511:0] q );always (posedge clk) begin…...

什么是API ?
API(应用程序编程接口) 就像现成的家具套件相对于家居建设,用一些已经切好的木板组装一个书柜,显然比自己设计,寻找合适的木材,裁切至合适的尺寸和形状,找到正确尺寸的螺钉,然后再组…...

Pytest中conftest.py的用法
Pytest中conftest.py的用法 在官方文档中,描述conftest.py是一个本地插件的文件,简单的说就是在这个文件中编写的方法,可以在其他地方直接进行调用。 注意事项 只能在根目录编写conftest.py 插件加载顺序在搜集用例之前 基础用法 这里…...

java.lang.IllegalArgumentException: When allowCredentials is true
1.遇到的错误 java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value "*" since that cannot be set on the "Access-Control-Allow-Origin" response header. To allow credentials to a…...

vue折叠展开transition动画使用keyframes实现
需求,我正常的菜单功能有隐藏与显示功能,需要增加动画 打开的时候宽度从0到300,关闭的时候,宽度从300到0 <template> <div id"app"> <button click"toggleLength">Toggle Length</bu…...

书生·浦语大模型实战营-学习笔记5
LMDeploy 大模型量化部署实践 大模型部署背景 LMDeploy简介 轻量化、推理引擎、服务 核心功能-量化 显存消耗变少了 大语言模型是典型的访存密集型任务,因为它是decoder-by-decoder 先把数据量化为INT4存起来,算的时候会反量化为FP16 AWQ算法&a…...

10. Profile
1. 区分环境的配置 1.1. properties 配置 假设,一个应用的工作环境有:dev、test、prod 那么,我们可以添加 4 个配置文件: applcation.properties - 公共配置application-dev.properties - 开发环境配置application-test.proper…...

YOLO 自己训练一个模型
一、准备数据集 我的版本是yolov8 8.11 这个目录结构很重要 ultralytics-main | datasets|coco|train|val 二、训练 编写yaml 文件 # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] path…...

3.Eureka注册中心
3.Eureka注册中心 假如我们的服务提供者user-service部署了多个实例,如图: 大家思考几个问题: order-service在发起远程调用的时候,该如何得知user-service实例的ip地址和端口?有多个user-service实例地址࿰…...