【UEFI基础】EDK网络框架(TCP4)

TCP4

TCP4协议说明

相比UDP4,TCP4是一种面向连接的通信协议,因此有更好的可靠性。

TCP4的首部格式如下:

在这里插入图片描述

各个参数说明如下:

字段长度(bit)含义
Source Port16源端口,标识哪个应用程序发送。
Destination Port16目的端口,标识哪个应用程序接收。
Sequence Number32序号字段。
TCP链接中传输的数据流中每个字节都编上一个序号。
序号字段的值指的是本报文段所发送的数据的第一个字节的序号。
Acknowledgment Number32确认号。
是期望收到对方的下一个报文段的数据的第1个字节的序号。
即上次已成功接收到的数据字节序号加1。
只有ACK标识为1,此字段有效。
Data Offset4数据偏移,即首部长度。
指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。
以32比特(4字节)为计算单位。
最多有60字节的首部,若无选项字段,正常为20字节。
Reserved6保留,必须填0。
URG1紧急指针有效标识。
它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。
ACK1确认序号有效标识。
只有当ACK=1时确认号字段才有效。当ACK=0时,确认号无效。
PSH1标识接收方应该尽快将这个报文段交给应用层。
接收到PSH = 1的TCP报文段,应尽快的交付接收应用进程,而不再等待整个缓存都填满了后再向上交付。
RST1重建连接标识。
当RST=1时,表明TCP连接中出现严重错误(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立连接。
SYN1同步序号标识,用来发起一个连接。
SYN=1表示这是一个连接请求或连接接受请求。
FIN1发端完成发送任务标识。
用来释放一个连接。
FIN=1表明此报文段的发送端的数据已经发送完毕,并要求释放连接。
Window16窗口:TCP的流量控制。
窗口起始于确认序号字段指明的值,这个值是接收端期望接收的字节数。
窗口最大为65535字节。
Checksum16校验字段,包括TCP首部和TCP数据,是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。
在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。
Urgent Pointer16紧急指针,只有当URG标志置1时紧急指针才有效。
TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。
紧急指针指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面)。
Options可变选项字段。
TCP协议最初只规定了一种选项,即最长报文段长度(只包含数据字段,不包括TCP首部),又称为MSS。
MSS告诉对方TCP“我的缓存所能接收的报文段的数据字段的最大长度是MSS个字节”。
新的RFC规定有以下几种选型:选项表结束,空操作,最大报文段长度,窗口扩大因子,时间戳。
* 选项表结束。
* 空操作:没有特殊含义,一般用于将TCP选项的总长度填充为4字节的整数倍。
* 最大报文段长度:又称为MSS,只包含数据字段,不包括TCP首部。
* 窗口扩大因子:3字节,其中一个字节表示偏移值S。新的窗口值等于TCP首部中的窗口位数增大到(16+S),相当于把窗口值向左移动S位后获得实际的窗口大小。
* 时间戳:10字节,其中最主要的字段是时间戳值(4字节)和时间戳回送应答字段(4字节)。
Padding可变填充字段,用来补位,使整个首部长度是4字节的整数倍。
data可变TCP负载。

对应UEFI中的代码:

typedef UINT32  TCP_SEQNO;
typedef UINT16  TCP_PORTNO;//
// TCP header definition
//
typedef struct {TCP_PORTNO    SrcPort;TCP_PORTNO    DstPort;TCP_SEQNO     Seq;TCP_SEQNO     Ack;UINT8         Res     : 4;UINT8         HeadLen : 4;UINT8         Flag;UINT16        Wnd;UINT16        Checksum;UINT16        Urg;
} TCP_HEAD;

TCP的连接过程大致如下:

在这里插入图片描述

TCP4代码综述

TCP4也是一个通用的网络协议,其实现在NetworkPkg\TcpDxe\TcpDxe.inf,这里首先需要看下它的入口:

EFI_STATUS
EFIAPI
TcpDriverEntryPoint (IN EFI_HANDLE        ImageHandle,IN EFI_SYSTEM_TABLE  *SystemTable)
{//// Install the TCP Driver Binding Protocol//Status = EfiLibInstallDriverBindingComponentName2 (ImageHandle,SystemTable,&gTcp4DriverBinding,ImageHandle,&gTcpComponentName,&gTcpComponentName2);//// Initialize ISS and random port.//Seed            = NetRandomInitSeed ();mTcpGlobalIss   = NET_RANDOM (Seed) % mTcpGlobalIss;mTcp4RandomPort = (UINT16)(TCP_PORT_KNOWN + (NET_RANDOM (Seed) % TCP_PORT_KNOWN));
}

因为TCP4也是一个UEFI Driver Model,所以第一步是安装gTcp4DriverBinding,其实现:

EFI_DRIVER_BINDING_PROTOCOL  gTcp4DriverBinding = {Tcp4DriverBindingSupported,Tcp4DriverBindingStart,Tcp4DriverBindingStop,0xa,NULL,NULL
};

而第二步是初始化一个随机的TCP端口,根据通用网络协议的做法,TCP的端口占两个字节(即16位),只要不是0-1023里面的公认端口都可以,且跟UDP端口的一致也没有关系。

最后还有一个mTcpGlobalIss,这里的ISS全称是Initial Sending Sequence,它的值本身不是很重要,从名字也知道它的作用就是指定TCP发送的第一个包的序列号,这是因为TCP一次发送的包可能会有很多,所以需要排序。

UDP4在UEFI网络协议栈中的关系图:

支持
提供
支持
支持
提供
支持
提供
提供
提供
支持
提供
提供
支持
支持
提供
提供
提供
支持
提供
提供
gEfiPciIoProtocolGuid
UNDI
gEfiNetworkInterfaceIdentifierProtocolGuid_31
gEfiDevicePathProtocolGuid
SNP
gEfiSimpleNetworkProtocolGuid
MNP
gEfiVlanConfigProtocolGuid
gEfiManagedNetworkServiceBindingProtocolGuid
gEfiManagedNetworkProtocolGuid
ARP
gEfiArpServiceBindingProtocolGuid
gEfiArpProtocolGuid
IP4
gEfiIp4ServiceBindingProtocolGuid
gEfiIp4Config2ProtocolGuid
gEfiIp4ProtocolGuid
UDP4
gEfiTcp4ServiceBindingProtocolGuid
gEfiTcp4ProtocolGuid

Tcp4DriverBindingSupported

TCP4依赖于IP4:

EFI_STATUS
EFIAPI
Tcp4DriverBindingSupported (IN EFI_DRIVER_BINDING_PROTOCOL  *This,IN EFI_HANDLE                   ControllerHandle,IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL)
{//// Test for the Ip4ServiceBinding Protocol//Status = gBS->OpenProtocol (ControllerHandle,&gEfiIp4ServiceBindingProtocolGuid,NULL,This->DriverBindingHandle,ControllerHandle,EFI_OPEN_PROTOCOL_TEST_PROTOCOL);return Status;
}

Tcp4DriverBindingStart

Start函数里面只有一个函数TcpCreateService(),它的作用就是初始化TCP_SERVICE_DATA

TCP_SERVICE_DATA

该结构体本身也比较简单:

typedef struct _TCP_SERVICE_DATA {UINT32                          Signature;EFI_HANDLE                      ControllerHandle;EFI_HANDLE                      DriverBindingHandle;UINT8                           IpVersion;IP_IO                           *IpIo;EFI_SERVICE_BINDING_PROTOCOL    ServiceBinding;LIST_ENTRY                      SocketList;
} TCP_SERVICE_DATA;

其重点其实就是一个SocketList,它对应列表成员是SOCKET

SOCKET

Socket就是TCP的子项。该结构体如下:

///
/// The socket structure representing a network service access point.
///
struct _TCP_SOCKET {//// Socket description information//UINT32                      Signature;     ///< Signature of the socketEFI_HANDLE                  SockHandle;    ///< The virtual handle of the socketEFI_HANDLE                  DriverBinding; ///< Socket's driver binding protocolEFI_DEVICE_PATH_PROTOCOL    *ParentDevicePath;EFI_DEVICE_PATH_PROTOCOL    *DevicePath;LIST_ENTRY                  Link;UINT8                       ConfigureState;SOCK_TYPE                   Type;UINT8                       State;UINT16                      Flag;EFI_LOCK                    Lock;         ///< The lock of socketSOCK_BUFFER                 SndBuffer;    ///< Send buffer of application's dataSOCK_BUFFER                 RcvBuffer;    ///< Receive buffer of received dataEFI_STATUS                  SockError;    ///< The error returned by low layer protocolBOOLEAN                     InDestroy;//// Fields used to manage the connection request//UINT32                      BackLog;        ///< the limit of connection to this socketUINT32                      ConnCnt;        ///< the current count of connections to itSOCKET                      *Parent;        ///< listening parent that accept the connectionLIST_ENTRY                  ConnectionList; ///< the connections maintained by this socket//// The queue to buffer application's asynchronous token//LIST_ENTRY                  ListenTokenList;LIST_ENTRY                  RcvTokenList;LIST_ENTRY                  SndTokenList;LIST_ENTRY                  ProcessingSndTokenList;SOCK_COMPLETION_TOKEN       *ConnectionToken; ///< app's token to signal if connectedSOCK_COMPLETION_TOKEN       *CloseToken;      ///< app's token to signal if closed//// Interface for low level protocol//SOCK_PROTO_HANDLER          ProtoHandler;                      ///< The request handler of protocolUINT8                       ProtoReserved[PROTO_RESERVED_LEN]; ///< Data fields reserved for protocolUINT8                       IpVersion;NET_PROTOCOL                NetProtocol;                      ///< TCP4 or TCP6 protocol socket used//// Callbacks after socket is created and before socket is to be destroyed.//SOCK_CREATE_CALLBACK        CreateCallback;  ///< Callback after createdSOCK_DESTROY_CALLBACK       DestroyCallback; ///< Callback before destroyedVOID                        *Context;        ///< The context of the callback
};

该结构体的创建来自SockCreate(),其调用流程:

TcpServiceBindingCreateChild
SockCreateChild
PktRcvdNotify
TcpRxCallback
TcpInput
TcpCloneTcb
SockClone
SockCreate

左边的PktRcvdNotify是IP4中的回调函数,右边就是常用的创建子项的函数。

SOCKET中的主要成员说明如下:

  • SockHandleNetProtocol:这两个参数需要一起看,它们的初始化位于SockCreate()函数中:
  Status = gBS->InstallMultipleProtocolInterfaces (&Sock->SockHandle,TcpProtocolGuid,&Sock->NetProtocol,NULL);

事实上就是安装了一个Protocol,对应的GUID是TcpProtocolGuid,它其实就是两个选择,v4和v6,对应到NetProtocol也就有了两个版本:

  if (SockInitData->IpVersion == IP_VERSION_4) {TcpProtocolGuid = &gEfiTcp4ProtocolGuid;ProtocolLength  = sizeof (EFI_TCP4_PROTOCOL);} else {TcpProtocolGuid = &gEfiTcp6ProtocolGuid;ProtocolLength  = sizeof (EFI_TCP6_PROTOCOL);}

我们需要关注的是gEfiTcp4ProtocolGuidEFI_TCP4_PROTOCOL,后者对应结构体:

struct _EFI_TCP4_PROTOCOL {EFI_TCP4_GET_MODE_DATA    GetModeData;EFI_TCP4_CONFIGURE        Configure;EFI_TCP4_ROUTES           Routes;EFI_TCP4_CONNECT          Connect;EFI_TCP4_ACCEPT           Accept;EFI_TCP4_TRANSMIT         Transmit;EFI_TCP4_RECEIVE          Receive;EFI_TCP4_CLOSE            Close;EFI_TCP4_CANCEL           Cancel;EFI_TCP4_POLL             Poll;
};

就是真正用于收发数据的TCP接口。

  • DriverBinding:这个值来自SOCK_INIT_DATA中的DriverBinding
Sock->DriverBinding       = SockInitData->DriverBinding;

而后者有来自TCP_SERVICE_DATA中的DriverBindingHandle

mTcpDefaultSockData.DriverBinding = TcpServiceData->DriverBindingHandle;

所以说到底SOCKET中的DriverBinding就是TCP_SERVICE_DATA中的DriverBindingHandle,最终就是EFI_DRIVER_BINDING_PROTOCOL中的DriverBindingHandle

  • ParentDevicePath:它跟上一个参数是有关联的:
  Status = gBS->OpenProtocol (TcpServiceData->ControllerHandle,&gEfiDevicePathProtocolGuid,(VOID **)&This->ParentDevicePath,TcpServiceData->DriverBindingHandle,This->SockHandle,EFI_OPEN_PROTOCOL_GET_PROTOCOL);

实际上就是代表网卡的设备路径,其值以字符串表示大概是这样的:

PciRoot(0x0)/Pci(0x2,0x0)/MAC(525400123456,0x1)

PCI路径可以不用关注,重点在于到MAC为止。

  • DevicePath:它是在ParentDevicePath之上增加了IPv4_DEVICE_PATH的结果:
  Sock->DevicePath = AppendDevicePathNode (Sock->ParentDevicePath, DevicePath);Status = gBS->InstallProtocolInterface (&Sock->SockHandle,&gEfiDevicePathProtocolGuid,EFI_NATIVE_INTERFACE,Sock->DevicePath);

其值以字符串表示大概是这样的:

PciRoot(0x0)/Pci(0x2,0x0)/MAC(525400123456,0x1)/IPv4(0.0.0.0)
  • Link:该值与TCP_SERVICE_DATA中的SocketList连接。
  • ConfigureState:表示Socket的配置状态,有以下的值:
///
/// Socket configure state
///
#define SO_UNCONFIGURED        0
#define SO_CONFIGURED_ACTIVE   1
#define SO_CONFIGURED_PASSIVE  2
#define SO_NO_MAPPING          3
  • Type:Socket有两种类型,分别是流格式套接字和数据报格式套接字,对应如下代码:
///
///  The socket type.
///
typedef enum {SockDgram, ///< This socket providing datagram serviceSockStream ///< This socket providing stream service
} SOCK_TYPE;

流格式套接字也叫“面向连接的套接字”,它有以下的特征:

  1. 数据在传输过程中不会消失;
  2. 数据是按照顺序传输的;
  3. 数据的发送和接收不是同步的(有的教程也称“不存在数据边界”)。

数据报格式套接字也叫“无连接的套接字”,它有以下的特征:

  1. 强调快速传输而非传输顺序;
  2. 传输的数据可能丢失也可能损毁;
  3. 限制每次传输的数据大小;
  4. 数据的发送和接收是同步的(有的教程也称“存在数据边界”)。
  • State:表示Socket本身的状态,有如下的值:
///
/// Socket state
///
#define SO_CLOSED         0
#define SO_LISTENING      1
#define SO_CONNECTING     2
#define SO_CONNECTED      3
#define SO_DISCONNECTING  4
  • Flag:表示TCP头部中的标识,有如下的值:
///
/// Flags in the TCP header
///
#define TCP_FLG_FIN  0x01
#define TCP_FLG_SYN  0x02
#define TCP_FLG_RST  0x04
#define TCP_FLG_PSH  0x08
#define TCP_FLG_ACK  0x10
#define TCP_FLG_URG  0x20

在TCP4协议说明可以找到它们的说明。

  • SndBufferRcvBuffer:收发数据使用的缓存。
  • SockError:Socket的状态。
  • BackLog:表示Socket连接数上限。
  • ConnCnt:表示当前的Socket连接数。
  • Parent:它的类型也是SOCKET,从这里可以看出来Socket之间也有父子关系。从前面的调用流程可以看到,Socket可以通过SockCreate()函数创建,而后者又由两个函数调用:
SockCreateChild
SockCreate
SockClone

它们对应的入参是不同的,SockCreateChild()的入参是mTcpDefaultSockData

SOCK_INIT_DATA  mTcpDefaultSockData = {SockStream,SO_CLOSED,NULL,	// ParentTCP_BACKLOG,TCP_SND_BUF_SIZE,TCP_RCV_BUF_SIZE,IP_VERSION_4,NULL,TcpCreateSocketCallback,TcpDestroySocketCallback,NULL,NULL,0,TcpDispatcher,NULL,
};

SockClone()的实现:

SOCKET *
SockClone (IN SOCKET  *Sock)
{SOCKET          *ClonedSock;SOCK_INIT_DATA  InitData;InitData.BackLog         = Sock->BackLog;InitData.Parent          = Sock;	// 注意这里的ParentInitData.State           = Sock->State;InitData.ProtoHandler    = Sock->ProtoHandler;InitData.Type            = Sock->Type;InitData.RcvBufferSize   = Sock->RcvBuffer.HighWater;InitData.SndBufferSize   = Sock->SndBuffer.HighWater;InitData.DriverBinding   = Sock->DriverBinding;InitData.IpVersion       = Sock->IpVersion;InitData.Protocol        = &(Sock->NetProtocol);InitData.CreateCallback  = Sock->CreateCallback;InitData.DestroyCallback = Sock->DestroyCallback;InitData.Context         = Sock->Context;InitData.ProtoData       = Sock->ProtoReserved;InitData.DataSize        = sizeof (Sock->ProtoReserved);ClonedSock = SockCreate (&InitData);

从这里带出了新的父子关系。实际的测试中发现,SockCreateChild()会在启动中执行,并且Parent的值都是0,而SockClone()会在使用TCP时创建Socket,此时的Parent是一个有效的值。

  • ConnectionList:当前Socket维护的连接。
  • ListenTokenListRcvTokenListSndTokenListProcessingSndTokenList:处理收发数据的Token列表。
  • ConnectionToken:Socket连接后调用的Token。
  • CloseToken:Socket关闭时调用的Token。
  • ProtoHandlerProtoReserved:Socket请求的回调函数以及对应的入参,回调函数就是TcpDispatcher(),根据入参会执行不同的操作:
EFI_STATUS
TcpDispatcher (IN SOCKET  *Sock,IN UINT8   Request,IN VOID    *Data    OPTIONAL)
{switch (Request) {case SOCK_POLL:case SOCK_CONSUMED:case SOCK_SND:case SOCK_CLOSE:case SOCK_ABORT:case SOCK_SNDPUSH:case SOCK_SNDURG:case SOCK_CONNECT:case SOCK_ATTACH:case SOCK_FLUSH:case SOCK_DETACH:case SOCK_CONFIGURE:case SOCK_MODE:case SOCK_ROUTE:default:}
}
  • IpVersion:这里就是IP_VERSION_4
  • CreateCallbackDestroyCallbackContext:对应mTcpDefaultSockData中的函数,以及它们的入参。

EFI_TCP4_PROTOCOL

该Protocol的结构体如下:

///
/// The EFI_TCP4_PROTOCOL defines the EFI TCPv4 Protocol child to be used by
/// any network drivers or applications to send or receive data stream.
/// It can either listen on a specified port as a service or actively connected
/// to remote peer as a client. Each instance has its own independent settings,
/// such as the routing table.
///
struct _EFI_TCP4_PROTOCOL {EFI_TCP4_GET_MODE_DATA    GetModeData;EFI_TCP4_CONFIGURE        Configure;EFI_TCP4_ROUTES           Routes;EFI_TCP4_CONNECT          Connect;EFI_TCP4_ACCEPT           Accept;EFI_TCP4_TRANSMIT         Transmit;EFI_TCP4_RECEIVE          Receive;EFI_TCP4_CLOSE            Close;EFI_TCP4_CANCEL           Cancel;EFI_TCP4_POLL             Poll;
};

对应的实现在NetworkPkg\TcpDxe\TcpDriver.c:

EFI_TCP4_PROTOCOL  gTcp4ProtocolTemplate = {Tcp4GetModeData,Tcp4Configure,Tcp4Routes,Tcp4Connect,Tcp4Accept,Tcp4Transmit,Tcp4Receive,Tcp4Close,Tcp4Cancel,Tcp4Poll
};

相比于其它的网络Protocol,这个稍有不同,它包含了Connect、Accept、Close等TCP常用操作。

后面会介绍这些函数的实现。

Tcp4.Connect

对应的实现是Tcp4Connect,其实现是Socket的连接:

EFI_STATUS
EFIAPI
Tcp4Connect (IN EFI_TCP4_PROTOCOL          *This,IN EFI_TCP4_CONNECTION_TOKEN  *ConnectionToken)
{return SockConnect (Sock, ConnectionToken);
}

其它的Tcp4Accept、Tcp4Transmit、Tcp4Receive、Tcp4Close等也都是Socket的操作。

TCP代码示例

TCP的代码示例可以在beni/BeniPkg/DynamicCommand/TestDynamicCommand/TestTcp.c · jiangwei/edk2-beni - 码云 - 开源中国 (gitee.com)中找到,它实际上来自EmbeddedPkg\Drivers\AndroidFastbootTransportTcpDxe\FastbootTransportTcpDxe.inf,这是一个开源的模块,不过在编译过程中会报错,所以这里进行了移植,对应BeniPkg\Dxe\TransportTcpDxe\TcpTransportDxe.inf,而TestTcp.c模块就是调用了这个模块。

它将开启一个TCP服务端,可以通过TCP客户端(这里使用了Packet Sender,来自Packet Sender - Free utility to for sending / receiving of network packets. TCP, UDP, SSL.)来与它交互。

其运行结果如下:

在这里插入图片描述

这里接收数据并打印出来,所以能够在右边Shell下看到左边程序传递过来的数据。

注意这里的Address(192.168.3.128)和Port(1234)是硬编码的,需要根据实际情况修改。

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

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

相关文章

2023年12月青少年机器人技术等级考试(三级)理论综合试卷

2023年12月青少年机器人技术等级考试&#xff08;三级&#xff09;理论综合试卷 单选题 第 1 题 单选题 下列选项中&#xff0c;关于光敏电阻描述正确的是&#xff1f;&#xff08; &#xff09; A. 光敏电阻是由导体材料制作而成 B. 光照射光敏电阻时&#xff0c;光照越强…

Python环境下一维时间序列信号的时频脊线追踪方法

瞬时频率是分析调频信号的一个重要参数&#xff0c;它表示了信号中的特征频率随时间的变化。使用短时傅里叶变换或小波变换获得信号的时频表示TFR后&#xff0c;从TFR中估计信号各分量的瞬时频率&#xff0c;即可获得信号中的特征信息。在TFR中&#xff0c;调频信号的特征分量通…

虚拟机将1.15版本的nginx推送到阿里云镜像仓库

1、docker images 2、docker login --usernamealiyun7279061146 registry.cn-shenzhen.aliyuncs.com 3、docker tag 53f3fd8007f7 registry.cn-shenzhen.aliyuncs.com/zhouwb/zhou:1.15 docker push registry.cn-shenzhen.aliyuncs.com/zhouwb/zhou:1.15

Android OpenGL EGL使用——自定义相机

如果要使用OpenGl来自定义相机&#xff0c;EGL还是需要了解下的。 可能大多数开发者使用过OpengGL但是不知道EGL是什么&#xff1f;EGL的作用是什么&#xff1f;这其实一点都不奇怪&#xff0c;因为Android中的GlSurfaceView已经将EGL环境都给配置好了&#xff0c;你一直在使用…

网络编程Day6

网络聊天室 服务器 #include <myhead.h> #define SER_IP "192.168.125.64" #define SER_PORT 6666 typedef struct Msg {char user[32]; //用户名int type; //1.登录、2.发消息、0.退出char text[1024]; //消息 } msg_t; typedef struct List {stru…

Opencv轮廓检测运用与理解

目录 引入 基本理解 加深理解 ①比如我们可以获取我们的第一个轮廓,只展示第一个轮廓 ②我们还可以用一个矩形把我们的轮廓给框出来 ③计算轮廓的周长和面积 引入 顾名思义,就是把我们图片的轮廓全部都描边出来 也就是我们在日常生活中面部识别的时候会有一个框,那玩意就…

华南理工大学数字信号处理实验实验二源码(薛y老师)

一、实验目的 ▪ 综合运用数字信号处理的理论知识进行信号分析并利用MATLAB作为编程工具进行计算机实现&#xff0c;从而加 深对所学知识的理解&#xff0c;建立概念。 ▪ 掌握数字信号处理的基本概念、基本理论和基本方法。 ▪ 学会用MATLAB对信号进行分析和处理。 ▪ 用F…

PS滤镜插件:Adobe Camera Raw 16 for Mac中文激活版

Adobe Camera Raw是Adobe公司开发的一款用于处理数码相机RAW格式文件的软件插件。它可以在Adobe Photoshop、Adobe Bridge和Adobe Lightroom等软件中使用&#xff0c;用于调整RAW文件的曝光、白平衡、对比度、色彩饱和度、锐化等参数&#xff0c;从而得到更好的图像质量。 软件…

python批量复制图片到execl并指定图片的大小

工作需要需要复制批量图片到execl&#xff0c;并指定大小&#xff0c;这里简单实现一下&#xff0c;使用xlwings库来实现总体来说是比较简单的&#xff0c;这里简单记录一下 import xlwings as xw import os# 创建一个可见的Excel应用程序对象 app xw.App(visibleTrue)# 打开…

idea远程服务调试

1. 配置idea远程服务调试 这里以 idea 新 ui 为例&#xff0c;首先点击上面的 debug 旁边的三个小圆点&#xff0c;然后在弹出的框框中选择 “Edit”&#xff0c;如下图所示。 然后进入到打开的界面后&#xff0c;点击左上角的 “” 进行添加&#xff0c;找到 “Remote JVM De…

XSS漏洞:一道关于DOM型XSS的题目

目录 解法1&#xff1a;SVG标签 DOM树的构建 img标签没有执行成功原因 svg标签执行成功的原因 总结 解法2&#xff1a;details标签 事件触发流程 总结 解法3&#xff1a;Dom-Clobbring 一个简单的例子来了解DOM劫持 toString 解决问题 xss系列往期文章&#xff1a; …

VC++中使用OpenCV进行形状和轮廓检测

VC中使用OpenCV进行形状和轮廓检测 在VC中使用OpenCV进行形状和轮廓检测&#xff0c;轮廓是形状分析以及物体检测和识别的有用工具。如下面的图像中Shapes.png中有三角形、矩形、正方形、圆形等&#xff0c;我们如何去区分不同的形状&#xff0c;并且根据轮廓进行检测呢&#…

初识React,基础(1), 安装react,jsx文件,类组件和函数组件,css样式

第一部分:初识react react: 用于构建用户界面的 JavaScript 库全局安装,win r, 命令: npm install create-react-app -g3. 创建一个react应用, 这里我在vscode 里面创建, 创建之后,运行 create-react-app my-appcd my-app npm start 第二部分: redact 组件定义以及使用 rea…

当 OpenTelemetry 遇上阿里云 Prometheus

作者&#xff1a;逸陵 背景 在云原生可观测蓬勃发展的当下&#xff0c;想必大家对 OpenTelemetry & Prometheus 并不是太陌生。OpenTelemetry 是 CNCF&#xff08;Cloud Native Computing Foundation&#xff09;旗下的开源项目&#xff0c;它的目标是在云原生时代成为应…

【Unity学习笔记】New Input System 部分源码和测试用例补充

转载请注明出处&#xff1a;&#x1f517;https://blog.csdn.net/weixin_44013533/article/details/135630016 作者&#xff1a;CSDN|Ringleader| 主要参考&#xff1a; Unity官方Input System手册与API【Unity学习笔记】Unity TestRunner使用【Unity学习笔记】第十二 New Inp…

MySQL的执行流程

一、MySQL的执行流程 MySQL架构分为Server层、存储引擎&#xff0c;其中Server层又分为连接器、查询缓存、分析器、优化器执行器五个部分。当客户端发送请求后依次需要经过 处理请求、查询缓存、语法解析、查询优化、存储引擎部分。 1. 连接器 负责维持和管理连接&#xff…

【差分数组】【图论】【分类讨论】【整除以2】100213按距离统计房屋对数目

作者推荐 【动态规划】【数学】【C算法】18赛车 本文涉及知识点 差分数组 图论 分类讨论 整除以2 LeetCode100213按距离统计房屋对数目 给你三个 正整数 n 、x 和 y 。 在城市中&#xff0c;存在编号从 1 到 n 的房屋&#xff0c;由 n 条街道相连。对所有 1 < i < n…

Java代码审计Shiro反序列化CB1链source入口sink执行gadget链

目录 0x00 前言 0x01 CC链&CB链简介 1. Commons Collections链是什么&#xff1f; 2. Commons BeanUtils链是什么&#xff1f; 0x02 测试Commons BeanUtils1链 0x03 Shiro550 - Commons BeanUtils1链 - 跟踪分析&#xff08;无依赖&#xff09; 1. 前置知识 2. Co…

Node开发基础

1. 概述 1.1 为什么要学习服务器端开发基础 能够和后端程序员更加紧密的配合 网站业务逻辑前置&#xff0c;学习前端技术需要后端技术支撑 扩宽知识视野&#xff0c;能够站在更高的角度审视整个项目 1.2 服务器端开发要做的事情 实现网站的业务逻辑 ---网站登录部分&#…