[米联客-安路飞龙DR1-FPSOC] UDP通信篇连载-04 IP层程序设计

软件版本:Anlogic -TD5.9.1-DR1_ES1.1

操作系统:WIN10 64bit

硬件平台:适用安路(Anlogic)FPGA

实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板

板卡获取平台:https://milianke.tmall.com/

登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!

3.3 IP层

ICMP层数据和UDP层数据都要经过IP层打包或者解包,IP层主要功能为判断数据报文类型,进行IP首部校验,添加包头或者过滤包头,处理ICMP请求。

3.3.1 IP接收模块

该模块的主要功能是接收uiip_arp_rx传入的数据包,通过首部校验判断包头的正确性,对包头进行过滤,并且提取出UDP报文和ICMP报文。

该模块的状态机转换图如图所示。

WAIT_IP_PACKET:等待接收IP包,若I_ip_rvalid拉高,代表数据传入,进入RECORD_IP_HEADER状态。

RECORD_IP_HEADER:接收包头信息,20字节的包头数据全部接收完时,判断收到的IP地址和本地IP地址是否匹配,若不匹配,丢弃该帧,进入WAIT_PACKET_END状态;若匹配,则判断数据包类型。如果收到的数据报文为UDP数据报文,进入OUTPUT_UDP_PACKET状态。如果收到的数据报文为ICMP报文,则将数据传入ICMP子层模块,等待一包数据传输完成后,进入WAIT_PACKET_END状态。

OUTPUT_UDP_PACKET:将有效数据打拍后传输至UDP层,一包数据传输完成后,回到WAIT_IP_PACKET状态。

WAIT_PACKET_END:等待数据有效信号拉低,一帧数据传输完成,回到WAIT_IP_PACKET状态。

always@(posedge I_ip_clk or posedge I_reset) beginif(I_reset) begincnt                     <= 5'd0;ip_version              <= 4'd0;    //IP首部-版本:4位数据表示IP版本号,为4时表示IPv4,为6时表示IPv6,IPv4使用较多。ip_header_len           <= 4'd0;    //IP首部-首部长度:4位数据表示IP首部一共有多少个32位(4个字节)数据。没有可选字段的IP首部长度为20个字节,故首部长度为5ip_tos                  <= 8'd0;    //IP首部-服务类型:8位服务类型被划分成两个子字段:3位优先级字段和4位TOS字段,最后一位固定为0。服务类型为0时表示一般服务。ip_pkg_len              <= 16'd0;   //IP首部-总长度:16位IP数据报总长度包括IP首部和IP数据部分,以字节为单位。利用IP首部长度和IP数据报总长度可以计算出IP数据报中数据内容的起始位置和长度ip_packet_id            <= 16'd0;   //IP首部-ID:16位标识字段,用来标识主机发送的每一份数据报。每发送一份报文它的值就会加1ip_packet_flag          <= 3'd0;    //IP首部-标志字段:3位标志字段的第1位是保留位,第2位表示禁止分片(1表示不分片,0允许分片),第3位标识更多分片,通常为010不分片ip_fragment_offset      <= 13'd0;   //IP首部-片偏移:13位片偏移,在接收方进行数据报重组时用来标识分片的顺序。ip_packet_ttl           <= 8'd0;    //IP首部-生存时间:    8位生存时间防止丢失的数据包在无休止的传播,一般被设置为64或者128ip_packet_protocol      <= 8'd0;    //IP首部-协议:8位协议类型表示此数据报所携带上层数据使用的协议类型,ICMP为1,TCP为6,UDP为17ip_header_checksum      <= 16'd0;   //IP首部-首部校验和:16位首部校验和,该字段只校验数据报的首部,不包含数据部分ip_src_address          <= 32'd0;   //IP首部-源IP地址:32位发送端的IP地址ip_dst_address          <= 32'd0;   //IP首部-目的IP地址:32位接收端的IP地址icmp_pkg_valid          <= 1'b0;    //icmp数据报文有效信号O_udp_ip_rvalid         <= 1'b0;    //UDP数据包有效O_udp_ip_rdata          <= 8'd0;    //UDP数据包有效输出STATE                   <= WAIT_IP_PACKET;endelse begincase(STATE)WAIT_IP_PACKET:beginif(I_ip_rvalid) beginip_version          <=  I_ip_rdata[7:4];    //IP首部-版本:4位数据表示IP版本号ip_header_len       <=  I_ip_rdata[3:0];    //IP首部-首部长度:4位数据表示IP首部一共有多少个32位(4个字节)数据STATE               <=  RECORD_IP_HEADER;   //下一状态,继续接收IP头部信息endelseSTATE               <=  WAIT_IP_PACKET;endRECORD_IP_HEADER:begincase(cnt)0:  begin   ip_tos                      <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-服务类型:8位服务类型被划分成两个子字段:3位优先级字段和4位TOS字段,最后一位固定为0。服务类型为0时表示一般服务。1:  begin   ip_pkg_len[15:8]            <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-总长度:16位IP数据报总长度包括IP首部和IP数据部分,以字节为单位。2:  begin   ip_pkg_len[7:0]             <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-总长度:16位IP数据报总长度包括IP首部和IP数据部分,以字节为单位。3:  begin   ip_packet_id[15:8]          <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-ID:16位标识字段,用来标识主机发送的每一份数据报。4:  begin   ip_packet_id[7:0]           <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-ID:16位标识字段,用来标识主机发送的每一份数据报。5:  begin   ip_packet_flag                      <=  I_ip_rdata[7:5];    //IP首部-标志字段:3位标志字段的第1位是保留位,第2位表示禁止分片(1表示不分片,0允许分片),第3位标识更多分片,通常为010不分片ip_fragment_offset[12:8]            <=  I_ip_rdata[4:0];    //IP首部-片偏移:13位片偏移,在接收方进行数据报重组时用来标识分片的顺序。cnt <=  cnt + 1'b1;end 6:  begin   ip_fragment_offset[7:0]     <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-片偏移:13位片偏移,在接收方进行数据报重组时用来标识分片的顺序。7:  begin   ip_packet_ttl[7:0]          <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-生存时间:8位生存时间防止丢失的数据包在无休止的传播,一般被设置为64或者1288:  begin   ip_packet_protocol[7:0]     <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-协议:8位协议类型表示此数据报所携带上层数据使用的协议类型,ICMP为1,TCP为6,UDP为17    9:  begin   ip_header_checksum[15:8]    <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-首部校验和:16位首部校验和,该字段只校验数据报的首部,不包含数据部分10: begin   ip_header_checksum[7:0]     <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-首部校验和:16位首部校验和,该字段只校验数据报的首部,不包含数据部分11: begin   ip_src_address[31:24]       <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-源IP地址:32位发送端的IP地址12: begin   ip_src_address[23:16]       <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-源IP地址:32位发送端的IP地址13: begin   ip_src_address[15:8]        <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-源IP地址:32位发送端的IP地址14: begin   ip_src_address[7:0]         <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-源IP地址:32位发送端的IP地址15: begin   ip_dst_address[31:24]       <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-目的IP地址:32位接收端的IP地址16: begin   ip_dst_address[23:16]       <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-目的IP地址:32位接收端的IP地址17: begin   ip_dst_address[15:8]        <=  I_ip_rdata; cnt <=  cnt + 1'b1;end  //IP首部-目的IP地址:32位接收端的IP地址18: begin   ip_dst_address[7:0]         <=  I_ip_rdata;                         //IP首部-目的IP地址:32位接收端的IP地址cnt                         <=  5'd0;if({ip_dst_address[31:8], I_ip_rdata} == I_ip_local_addr) begin     //如果收到的IP地址和本地IP地址匹配if(ip_packet_protocol == ICMP_TYPE) begin                       //如果是ICMP类型icmp_pkg_valid      <=  1'b1;                               //ICMP包有效           STATE               <=  WAIT_PACKET_END;                    //等待传输结束状态endelse if(ip_packet_protocol == UDP_TYPE) begin                   //如果是UDP包有效 icmp_pkg_valid      <=  1'b0;STATE               <=  OUTPUT_UDP_PACKET;                  //输出UDP包到UDP协议层endelse beginicmp_pkg_valid      <=  1'b0;STATE               <=  WAIT_PACKET_END;                    //等待传输结束状态endendelse beginicmp_pkg_valid          <=  1'b0;STATE                   <=  WAIT_PACKET_END;                    //等待传输结束状态endend endcaseendOUTPUT_UDP_PACKET:beginif(I_ip_rvalid) begin       //打拍后支持输出给UDP协议层O_udp_ip_rvalid         <=  1'b1;O_udp_ip_rdata          <=  I_ip_rdata;STATE                   <=  OUTPUT_UDP_PACKET;endelse beginO_udp_ip_rvalid         <=  1'b0;O_udp_ip_rdata          <=  8'd0;STATE                   <=  WAIT_IP_PACKET;                 end     endWAIT_PACKET_END:begin           //等待包传输结束if(I_ip_rvalid)STATE                   <=  WAIT_PACKET_END;else beginicmp_pkg_valid          <=  1'b0;STATE                   <=  WAIT_IP_PACKET;end     endendcaseend     
end

3.3.2 IP发送模块

该模块的主要功能有:接收uiudp_tx发送的UDP报文和uiip_rx发送的ICMP报文信息,将其封装成IP包并发送至下层uiip_arp_tx模块。

该模块的状态机转换图如图所示。

IDLE:uiip_tx模块处于发送空闲时,接收ICMP和UDP报文发送请求,优先响应ICMP请求。当收到请求时,向uiip_arp_tx模块发送请求信号,通过udp_pkg_en信号标记报文类型,进入WAIT_ACK状态,等待握手响应信号。

WAIT_ACK:接收到I_ip_tbusy信号,代表和IP_ARP层模块握手成功,可以发送数据,进入SEND_IP_HEADER状态。若要发送的是UDP报文,则会发送O_ip_udp_tbusy信号和UDP层进行握手。

SEND_IP_HEADER:在有效数据报文前添加对应的IP包头,发送包头完毕后,若报文类型为UDP报文,进入SEND_UDP_PACKET状态;若为ICMP报文,则进入SEND_ICMP_PACKET状态。

SEND_UDP_PACKET和SEND_ICMP_PACKET:发送完报文中的有效数据后,将标识加1,回到IDLE状态。

case(STATE)IDLE:beginif(icmp_pkg_req & (~I_ip_tbusy)) begin          //如果有ICMP包需要发送,并且ip_arp_tx模块处于空闲(I_ip_tbusy==0代表tbuf空闲,不在发送数据)O_ip_treq           <=  1'b1;               //通知ip_arp_tx模块,有IP包需要发送(ICMP包也是IP包)O_ip_udp_tbusy      <=  1'b0;               //通知udp_layer模块,目前不能发送UDP数据包O_ip_taddr          <=  icmp_pkg_ip_addr;   //保存ip_rx模块接收到的icmp请求的IP地址(因为发送icmp包需要通过IP地址获取远程主机的MAC地址)udp_pkg_en          <=  1'b0;               //标记是否是udp包,但udp_pkg_en=1 代表ip层发送的数据为UDP包STATE               <=  WAIT_ACK;endelse if(I_ip_udp_treq & (~I_ip_tbusy)) begin    //如果有UDP包需要发送O_ip_treq           <=  1'b1;               //输出ip包发送请求,给ip_arp_tx模块O_ip_udp_tbusy      <=  1'b0;               //通知udp_layer模块,目前不能发送UDP数据包O_ip_taddr          <=  I_ip_dest_addr;     //udp层提供需要发送的目的主机的IP地址udp_pkg_en          <=  1'b1;               //标记是否是udp包,但udp_pkg_en=1 代表ip层发送的数据为UDP包STATE               <=  WAIT_ACK;endelse beginO_ip_udp_tbusy      <=  1'b0;O_ip_treq           <=  1'b0;udp_pkg_en          <=  1'b0;STATE               <=  IDLE;endendWAIT_ACK:beginif(I_ip_tbusy) begin//当发送O_ip_treq后,如果ip_arp_tx模块返回I_ip_tbusy=1 代表ip_layer可以发送IP包(UDP包和ICMP包)到ip_arp_tx模块O_ip_treq           <=  1'b0;O_ip_udp_tbusy      <=  udp_pkg_en ? 1 : 0; //如果udp_pkg_en有效代表发的是UDP包STATE               <=  SEND_IP_HEADER;     //发送IP帧头endelse beginO_ip_treq           <=  1'b1;O_ip_udp_tbusy      <=  1'b0;STATE               <=  WAIT_ACK;                   endendSEND_IP_HEADER:begin//发送IP包帧头case(cnt)0   :beginif(I_ip_udp_tvalid | (~udp_pkg_en)) begin       //如果是UDP报文包需要发送或者udp_pkg_en==0 是ICMP报文包O_ip_tdata      <=  {VERSION, IHL};         //版本|首部长度(IP首部一共有多少个32bit数据)O_ip_tvalid     <=  1'b1;                   //通知tbuf IP数据有效packet_id       <=  ID_BASE + datagram_cnt; //标识,每发送1包该值加1TTL             <=  8'h80;                  //生存时间  if(!udp_pkg_en) begin                       //如果是ICMP包ip_tdata_length     <=  icmp_pkg_data_len + (IHL << 2); //IP包总长度(IP数据长度+IP首部长度) PROTOCOL            <=  8'h01;                          //IP包类型为 ICMP包endelse beginip_tdata_length     <=  I_ip_udp_tdata_len + (IHL << 2);PROTOCOL            <=  8'h11;                          //IP包类型为 UDP包endcnt             <=  cnt + 1'b1;endelsecnt             <=  5'd0;end1   :begin  O_ip_tdata  <=  TOS;                            cnt <=  cnt + 1'b1;end//服务类型2   :begin  O_ip_tdata  <=  ip_tdata_length[15:8];          cnt <=  cnt + 1'b1;end//IP包总长度3   :begin  O_ip_tdata  <=  ip_tdata_length[7:0];           cnt <=  cnt + 1'b1;end//IP包总长度4   :begin  O_ip_tdata  <=  packet_id[15:8];                cnt <=  cnt + 1'b1;end//IP包标识符,每发送一份报文,其值加15   :begin  O_ip_tdata  <=  packet_id[7:0];                 cnt <=  cnt + 1'b1;end//IP包标识符,每发送一份报文,其值加16   :begin  O_ip_tdata  <=  {FLAG, FRAGMENT_OFFSET[12:8]};  cnt <=  cnt + 1'b1;end//标志字段3bit|片偏移共13bit7   :begin  O_ip_tdata  <=  FRAGMENT_OFFSET[7:0];           cnt <=  cnt + 1'b1;end//片偏移共13bit8   :begin  O_ip_tdata  <=  TTL;                            cnt <=  cnt + 1'b1;end//生存时间9   :begin  O_ip_tdata  <=  PROTOCOL;                       cnt <=  cnt + 1'b1;end//协议10  :begin  O_ip_tdata  <=  checksum[15:8];                 cnt <=  cnt + 1'b1;end//校验和11  :begin  O_ip_tdata  <=  checksum[7:0];                  cnt <=  cnt + 1'b1;end//校验和12  :begin  O_ip_tdata  <=  I_ip_local_addr[31:24];         cnt <=  cnt + 1'b1;end//源IP地址32bit13  :begin  O_ip_tdata  <=  I_ip_local_addr[23:16];         cnt <=  cnt + 1'b1;end//源IP地址32bit14  :begin  O_ip_tdata  <=  I_ip_local_addr[15:8];          cnt <=  cnt + 1'b1;end//源IP地址32bit15  :begin  O_ip_tdata  <=  I_ip_local_addr[7:0];           cnt <=  cnt + 1'b1;end//源IP地址32bit16  :begin                          //目的IP地址(远端主机IP地址)if(!udp_pkg_en)                 //ICMP报文包O_ip_tdata      <=  icmp_pkg_ip_addr[31:24];else                            //UDP报文包O_ip_tdata      <=  O_ip_taddr[31:24];cnt     <=  cnt + 1'b1;end                 17  :begin                          //目的IP地址(远端主机IP地址)if(!udp_pkg_en)                 //ICMP报文包O_ip_tdata      <=  icmp_pkg_ip_addr[23:16];else                            //UDP报文包O_ip_tdata      <=  O_ip_taddr[23:16];cnt     <=  cnt + 1'b1;end18  :begin                          //目的IP地址(远端主机IP地址)if(!udp_pkg_en) beginO_ip_tdata      <=  icmp_pkg_ip_addr[15:8];icmp_pkg_busy   <=  1'b1;//icmp_pkg_tx代码上必须时序上,在SEND_ICMP_PACKET状态输出ICMP报文包endelse beginO_ip_tdata      <=  O_ip_taddr[15:8];icmp_pkg_busy   <=  1'b0;endcnt         <=  cnt + 1'b1;end19  :begin                          //目的IP地址(远端主机IP地址)cnt <=  5'd0;if(!udp_pkg_en) beginO_ip_tdata      <=  icmp_pkg_ip_addr[7:0];STATE           <=  SEND_ICMP_PACKET;endelse beginO_ip_tdata      <=  O_ip_taddr[7:0];STATE           <=  SEND_UDP_PACKET;endenddefault:    cnt <=  5'd0;endcaseendSEND_UDP_PACKET:begin                   //发送UDP报文包if(trans_data_cnt == (ip_tdata_length - 16'd20)) begin  //20个字节为IP首部,这里相等代表数据发送结束   O_ip_udp_tbusy      <=  1'b0;O_ip_tvalid         <=  1'b0;O_ip_tdata          <=  8'd0;datagram_cnt        <=  datagram_cnt + 16'h0001;    //没发送完1帧报文,该值加1trans_data_cnt      <=  16'd0;STATE               <=  IDLE;endelse begin                          //发送有效的UDP报文数据部分O_ip_tvalid         <=  1'b1;O_ip_tdata          <=  shift_data_out;         //从shift移位寄存器移出数据trans_data_cnt      <=  trans_data_cnt + 1'b1;  //UDP报文包有效数据部分计数器STATE               <=  SEND_UDP_PACKET;endendSEND_ICMP_PACKET:begin                  //发送ICMP报文包if(icmp_pkg_valid) beginO_ip_tvalid         <=  1'b1;O_ip_tdata          <=  icmp_pkg_data;STATE               <=  SEND_ICMP_PACKET;endelse beginO_ip_tvalid         <=  1'b0;O_ip_tdata          <=  8'd0;icmp_pkg_busy       <=  1'b0;datagram_cnt        <=  datagram_cnt + 16'h0001;//每发送完1帧报文,该值加1STATE               <=  IDLE;                   endendendcase

3.3.3 IP首部校验模块

        正常计算IP首部校验和时,将校验位置0。由于每两字节数据相加得到的不再产生进位结果,为最终校验和的取反,所以当计算过程中加入校验位时,相加得到的结果应当为全1。若结果不为全1,则数据校验错误,将O_check_rerror信号置为高。

`timescale 1ns / 1psmodule ip_header_checksum(
input  wire         I_clk,
input  wire         I_reset,
input  wire         I_ip_rdata_valid,
input  wire [7:0]   I_ip_rdata,
output wire         O_checksum_rerror
);
reg checksum_correct;
assign O_checksum_rerror = ~checksum_correct;reg [1:0]  state;
reg [3:0]  cnt;
wire [16:0] tmp_accum1;
reg [15:0] accum1, accum2;assign tmp_accum1 = accum1 + accum2;always @(posedge I_clk or posedge I_reset) beginif(I_reset) beginstate               <= 2'd0;cnt                 <= 4'd0;accum1              <= 16'd0;accum2              <= 16'd0;       checksum_correct    <= 1'b1;            endelse begincase(state) 0: begin if(I_ip_rdata_valid) beginaccum1[15:8]            <= I_ip_rdata; state                   <= 2'd1; endelse beginaccum1[15:8]            <= 8'd0;state                   <= 2'd0;endend1: begin accum1[7:0]    <= I_ip_rdata; state <= 2'd2; end2: begin        if(cnt == 4'd9) beginif((tmp_accum1[15:0] + tmp_accum1[16]) != 16'hffff)checksum_correct    <= 1'b0;cnt                 <= 4'd0;state               <= 2'd3;endelse begin  accum2 <= tmp_accum1[15:0] + tmp_accum1[16];accum1[15:8]        <= I_ip_rdata;cnt                 <= cnt + 1'b1;                         state               <= 2'd1;endend3: beginaccum1                  <= 16'd0;accum2                  <= 16'd0;if(I_ip_rdata_valid)state       <= state;elsestate       <= 2'd0;end             endcaseend
end
endmodule

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

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

相关文章

学习笔记-MYSQL 事务

目录 一、什么是事务&#xff1f; 二、事务的四个特征&#xff08;ACID&#xff09;【面试常考项】 原子性&#xff08;Atomicity&#xff09; 一致性&#xff08;Consistency&#xff09; 隔离性&#xff08;Isolation&#xff09; 持久性&#xff08;Durability&#x…

Linux-理解shell

文章目录 5. 理解shell5.1 shell的类型5.2 交互shell和系统默认shell5.3 安装zsh shell程序5.4 shell的父子关系5.5 命令列表5.6 命令分组5.7 使用命令分组创建子shell5.8 子shell用法5.9 shell的非内建命令和内建命令5.9.1 非内建命令5.9.2 内建命令5.9.3 history和alias命令介…

AI9-文本识别

本章主要介绍文本识别算法的理论知识,包括背景介绍、算法分类和部分经典论文思路。 通过本章的学习,你可以掌握: 1. 文本识别的目标 2. 文本识别算法的分类 3. 各类算法的典型思想 1 背景介绍 文本识别是OCR(Optical Character Recognition)的一个子任务,其任务为识别一个…

基于 Redis 的分布式信号量 Spring Boot 集成 Redisson 使用 Semaphore 控制并发访问数量

目录 前言 pom yml Controller 演示 注意 前言 工作中开发过一个服务&#xff0c;这里记作A服务&#xff0c;主要功能是配置&#xff0c;部署以及调用云函数。其中配置云函数的功能里&#xff0c;有一个配置项是并发数&#xff0c;意思是同一时间最多能有多少个请求调用…

【MATLAB源码】数学建模基础教程(2)--层次分析法(评价类算法)

系列文章目录在最后面&#xff0c;各位同仁感兴趣可以看看&#xff01; 层次分析法 引言一、层次分析法的特点二、模型的建立求解过程 (1)问题的提出&#xff1a;实际问题的转化(2)建立层次结构模型(3)构造判断(成对比较)矩阵(4)一致性检验&#xff1a;三、层次分析法的优点与…

Codeforces Round 871 (Div. 4)(A~H)

比赛链接 Dashboard - Codeforces Round 871 (Div. 4) - Codeforces A. Love Story 找到与codeforces 有多少个不同的字符。 #include<bits/stdc.h> #define int long long #define TEST int T; cin >> T; while (T--) #define ios ios::sync_with_stdio(fals…

前端常用的性能优化方案

目录 性能分析工具lighthouseWebpack Bundle分析 开发阶段按需引入路由懒加载 打包阶段打包配置减少包体积配置压缩分包 资源预加载/预请求 部署阶段开启http2静态资源缓存gzip压缩 性能优化主要在三个阶段进行&#xff1a;开发阶段、开发结束后的打包阶段、项目部署上线阶段 首…

提升生产效率:APS高级计划排程系统在车间工序级排程的革命性应用

在制造业的数字化转型浪潮中&#xff0c;APS高级计划排程系统以凭借自身卓越的排程运算能力和应用灵活性&#xff0c;已经成为中大型制造业提升生产效率的关键工具。APS系统的介入&#xff0c;打通了传统ERP和MES等各类业务系统运营平台&#xff0c;并且通过产能均衡规划&#…

为什么我3d模型选择面选不到?---模大狮模型网

在展览3D模型设计行业中&#xff0c;设计师常常面临诸多技术挑战&#xff0c;其中之一是在模型编辑过程中遇到选择面的困难。这不仅影响了设计工作效率&#xff0c;还可能影响最终作品的质量和展示效果。本文将探讨在3D模型设计中为何会遇到“为什么我3D模型选择面选不到?”这…

【MySQL进阶篇】管理

1、系统数据库 MySQL数据库安装完成之后&#xff0c;自带以下四个数据库&#xff0c;具体作用如下&#xff1a; 数据库含义mysql存储MySQL服务器正常运行所需要的各种信息&#xff08;时区、主从、用户、权限等&#xff09;information_schema提供了访问数据库元数据的各种表…

实战OpenCV之环境安装与配置

OpenCV是什么 OpenCV&#xff0c;英文全称为Open Source Computer Vision Library&#xff0c;是一个开源的计算机视觉和机器学习软件库。它设计用于提供一系列功能强大的算法&#xff0c;以帮助开发者处理图像和视频数据&#xff0c;实现各种视觉任务&#xff0c;包括&#xf…

.NET内网实战:模拟Installer关闭Defender

01基本介绍 02编码实现 原理上通过Windows API函数将当前进程的权限提升至TrustedInstaller&#xff0c;从而实现了对Windows Defender服务的控制。通常可以利用Windows API中的OpenSCManager、OpenProcessToken、ImpersonateLoggedOnUser以及ControlService等函数协同工作&am…

从干涉实验、化学反应到晶体管的科学之旅 - 《量子宇宙》读后感

在《量子宇宙》这本书中&#xff0c;作者没有讲述历史和发现的故事&#xff0c;而是从头到尾用公式推导来展示宇宙和现代物理学的壮美。 量子理论处理的是概率&#xff0c;而不是确定性。大自然在某些方面本质上就是由或然率支配的。计算粒子出现的概率是我们能做到的极限。 …

渗透小游戏,各个关卡的渗透实例---步骤简单(含代码)

文章目录 Less-1Less-2Less-5updatexml报错注入&#xff1a; Less-6Less-7Less-8Less-9Less-11Less-13Less-15 Less-1 首先&#xff0c;可以看见该界面&#xff0c;该关卡主要是SQL注入&#xff0c;由于对用户的输入没有做过滤&#xff0c;使查询语句进入到了数据库中&#xff…

springboot电影院线上购票系统-计算机毕业设计源码68220

目录 摘要 1 绪论 1.1 选题背景与意义 1.2国内外研究现状 1.3论文结构与章节安排 2系统分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统流程分析 2.2.1 添加信息流程 2.2.2 修改信息流程 2.2.3 删除信息流程 2.3 系统功能分析 2.…

synchronized 与 Lock 的区别

synchronized 与 Lock 的区别 1、相同点2、不同点2.1 精确性与灵活性2.2 性能2.3 使用便利性 3、示例3.1 synchronized 示例3.2 Lock 示例 4、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Java多线程编程中&#xff0c;synchroniz…

智能家居沙盘系统-智慧家居沙盘系统

智能家居和物联网技术是当前科技领域的热门话题&#xff0c;随着各类智能家居产品的不断推出&#xff0c;智能家居市场也逐渐呈现出蓬勃发展的态势。智能家居快速发展&#xff0c;而物联网相关人才供应远远不足。高校开展智能家居工程及设计人才教育培养具有重大意义。 基本介绍…

【stm32】EXTI外部中断

EXTI外部中断 1、中断系统2、中断执行流程3、STM32中断4、NVIC基本结构5、NVIC优先级分组6、EXTI简介&#xff08;引脚电平变化&#xff0c;申请中断&#xff09;7、EXTI基本结构8、AFIO复用IO口9、EXTI框图10、旋转编码器简介11、程序设计&#xff1a;1.使用对射式红外传感器触…

vue3实现商品图片放大镜效果(芋道源码yudao-cloud 二开笔记)

今天开发一个防某商城的商品图片放大镜&#xff0c;鼠标移动到图片位置时&#xff0c;右侧出现一个已放大的图片效果。 示例如下&#xff1a; 下图的图片的放大效果和小图的切换封装成了组件PicShow.vue&#xff0c;可根据需求自行修改&#xff0c;如下&#xff1a; 第一步&…

Html5总结

前端学习 html决定页面的结构css决定页面的样式js决定页面的行为 Html5 1.文本格式化标签&#xff08;熟记&#xff09; 你在网页中&#xff0c;有时需要为文字设置粗体、斜体或下划线效果&#xff0c;这时就需要用到HTML中的文本格式化标记 2.标签属性 例如&#xff1a; …