10G UDP协议栈 (9)UDP模块

目录

一、UDP协议简单介绍

二、UDP功能实现

三、仿真

一、UDP协议简单介绍

UDP协议和TCP协议同位于传输层,介于网络层(IP)和应用层之间:UDP数据部分为应用层报文,而UDP报文在IP中承载。

UDP 报文格式相对于简单,如下图:


源端口:端口号0-65535,1-1024保留端口号,为标准的服务端口
目的端口:无须多解释
UDP长度:header+data 总长度
UDP校验和:伪头部,头部,data 三部分校验和。
数据:上层应用层的数据。

 UDP校验和计算:UDP校验和计算-CSDN博客

二、UDP功能实现

UDP_RX模块功能:接收IP层传递过来的数据,判断数据中的目的端口号是否与本节点的源端口号相同,同时执行UDP校验和计算。(由于此时的校验是对整个UDP首部+UDP伪首部+UDP数据进行校验,所以可以参考IP校验的方式,将数据暂存在一个RAM中,根据校验和的正确性控制地址的分配)。

UDP_TX模块功能:将上层传递过来的数据封装上UDP头,并进行UDP校验和计算。(此时的校验和计算可以先将封装完毕的UDP帧存储在一个RAM中,并在一帧的结尾单独对UDP校验和所在的地址进行操作)。

UDP_TX模块:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/05/22 10:38:55
// Design Name: 
// Module Name: UDP_TX
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//
module UDP_TX#(
    parameter           P_SOURCE_PORT = 16'd8080    ,
    parameter           P_TARGET_PORT = 16'd8080    
)(
    input               i_clk                       ,
    input               i_rst                       ,

    input  [15:0]       i_set_source_port           ,
    input               i_set_source_valid          ,
    input  [15:0]       i_set_target_port           ,
    input               i_set_target_valid          ,

    input  [63:0]       s_axis_user_data            ,
    input  [31:0]       s_axis_user_user            ,//16'dByteLen,16'dBrust
    input  [7 :0]       s_axis_user_keep            ,
    input               s_axis_user_last            ,
    input               s_axis_user_valid           ,
    output              s_axis_user_ready           ,

    output [63:0]       m_axis_ip_data              ,
    output [70:0]       m_axis_ip_user              ,//16'dByteLen,1'bMF,16'dlen,1'bsplit,8'dtype,13'doffset,16'dID
    output [7 :0]       m_axis_ip_keep              ,
    output              m_axis_ip_last              ,
    output              m_axis_ip_valid             ,
    input               m_axis_ip_ready             
);

reg  [15:0]             ri_set_source_port          ;
reg  [15:0]             ri_set_target_port          ;
reg  [63:0]             rs_axis_user_data           ;
reg  [31:0]             rs_axis_user_user           ;
reg  [7 :0]             rs_axis_user_keep           ;
reg                     rs_axis_user_last           ;
reg                     rs_axis_user_valid          ;
reg                     rs_axis_user_ready          ;
reg  [63:0]             rm_axis_ip_data             ;
reg  [70:0]             rm_axis_ip_user             ;
reg  [7 :0]             rm_axis_ip_keep             ;
reg                     rm_axis_ip_last             ;
reg                     rm_axis_ip_valid            ;
reg                     r_fifo_data_rden            ;
reg  [15:0]             r_cnt                       ;
reg  [7 :0]             r_last_keep                 ;
reg                     r_fifo_data_empty           ;
reg                     r_fifo_data_empty_1d        ;

wire [63:0]             w_fifo_data_dout            ;
wire                    w_fifo_data_full            ;
wire                    w_fifo_data_empty           ;

assign s_axis_user_ready = rs_axis_user_ready       ;
assign m_axis_ip_data  = rm_axis_ip_data            ;
assign m_axis_ip_user  = rm_axis_ip_user            ;
assign m_axis_ip_keep  = rm_axis_ip_keep            ;
assign m_axis_ip_last  = rm_axis_ip_last            ;
assign m_axis_ip_valid = rm_axis_ip_valid           ;
//将用户传输的数据缓存
FIFO_DATA_64X256 FIFO_DATA_64X256_u0 (
  .clk                  (i_clk                      ), 
  .srst                 (i_rst                      ),
  .din                  (rs_axis_user_data          ), 
  .wr_en                (rs_axis_user_valid         ),
  .rd_en                (r_fifo_data_rden           ),
  .dout                 (w_fifo_data_dout           ),
  .full                 (w_fifo_data_full           ),
  .empty                (w_fifo_data_empty          )
);

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst) begin
        r_fifo_data_empty <= 'd0;
        r_fifo_data_empty_1d <= 'd0;
    end else begin
        r_fifo_data_empty <= w_fifo_data_empty;
        r_fifo_data_empty_1d <= r_fifo_data_empty;
    end
end
//动态配置源端口、目的端口
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        ri_set_source_port <= P_SOURCE_PORT;
    else if(i_set_source_valid)
        ri_set_source_port <= i_set_source_port;
    else 
        ri_set_source_port <= ri_set_source_port;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        ri_set_target_port <= P_TARGET_PORT;
    else if(i_set_target_valid)
        ri_set_target_port <= i_set_target_port;
    else 
        ri_set_target_port <= ri_set_target_port;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst) begin
        rs_axis_user_data  <= 'd0;
        rs_axis_user_keep  <= 'd0;
        rs_axis_user_last  <= 'd0;
        rs_axis_user_valid <= 'd0;
    end else begin
        rs_axis_user_data  <= s_axis_user_data ;
        rs_axis_user_keep  <= s_axis_user_keep ;
        rs_axis_user_last  <= s_axis_user_last ;
        rs_axis_user_valid <= s_axis_user_valid;
    end
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst) 
        rs_axis_user_user <= 'd0;
    else if(s_axis_user_valid)
        rs_axis_user_user  <= s_axis_user_user ;
    else 
        rs_axis_user_user <= rs_axis_user_user;
end
//控制ready信号,当一帧输入时将ready信号拉低
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        rs_axis_user_ready <= 'd1;
    else if(s_axis_user_last)
        rs_axis_user_ready <= 'd0;
    else if(r_fifo_data_empty_1d)
        rs_axis_user_ready <= 'd1;
    else 
        rs_axis_user_ready <= rs_axis_user_ready;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_last_keep <= 'd0;
    else if(s_axis_user_last)
        r_last_keep <= s_axis_user_keep;
    else 
        r_last_keep <= r_last_keep;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_cnt <= 'd0;
    else if(r_cnt == rs_axis_user_user[15:0])
        r_cnt <= 'd0;
    else if(r_fifo_data_rden || r_cnt)
        r_cnt <= r_cnt + + 1;
    else 
        r_cnt <= r_cnt;
end
//控制fifo读使能,当FIFO不为空的时候开始读
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_fifo_data_rden <= 'd0;
    else if(r_cnt == rs_axis_user_user[15:0] - 1)
        r_fifo_data_rden <= 'd0;
    else if(!w_fifo_data_empty)
        r_fifo_data_rden <= 'd1;
    else         
        r_fifo_data_rden <= r_fifo_data_rden;
end 
//组UDP帧
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        rm_axis_ip_data <= 'd0;
    else case(r_cnt)
        0           :rm_axis_ip_data <= {ri_set_source_port,ri_set_target_port,rs_axis_user_user[31:16] + 16'd8,16'd0};//源端口号、目的端口号、UDP长度、UDP校验和(暂时为0)
        default     :rm_axis_ip_data <= w_fifo_data_dout;
    endcase
end
//控制Keep信号
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        rm_axis_ip_keep <= 'd0;
    else if(r_cnt && r_cnt == rs_axis_user_user[15:0] - 0)
        rm_axis_ip_keep <= r_last_keep;
    else 
        rm_axis_ip_keep <= 8'b1111_1111;
end
//控制Last信号
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        rm_axis_ip_last <= 'd0;
    else if(r_cnt && r_cnt == rs_axis_user_user[15:0] - 0)
        rm_axis_ip_last <= 'd1;
    else 
        rm_axis_ip_last <= 'd0;
end
//控制Valid信号
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        rm_axis_ip_valid <= 'd0;
    else if(rm_axis_ip_last)
        rm_axis_ip_valid <= 'd0;
    else if(r_fifo_data_rden)
        rm_axis_ip_valid <= 'd1;
    else        
        rm_axis_ip_valid <= rm_axis_ip_valid;
end

//16'dByteLen,1'bMF,16'dlen,1'bsplit,8'dtype,13'doffset,16'dID
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        rm_axis_ip_user <= 'd0;
    else 
        rm_axis_ip_user <= {rs_axis_user_user[31:16] + 16'd8,1'b0,rs_axis_user_user[15:0] + 16'd1,1'b0,8'd17,13'd0,16'd0};
end

endmodule

UDP_RX模块:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/05/22 10:38:55
// Design Name: 
// Module Name: UDP_RX
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

module UDP_RX#(
    parameter           P_SOURCE_PORT = 16'd8080    ,
    parameter           P_TARGET_PORT = 16'd8080    
)(
    input               i_clk                       ,
    input               i_rst                       ,

    input  [15:0]       i_set_source_port           ,
    input               i_set_source_valid          ,
    input  [15:0]       i_set_target_port           ,
    input               i_set_target_valid          ,

    input  [63:0]       s_axis_ip_data              ,
    input  [54:0]       s_axis_ip_user              ,//1'bMF,16'dlen,1'bsplit,8'dtype,13'doffset,16'dID
    input  [7 :0]       s_axis_ip_keep              ,
    input               s_axis_ip_last              ,
    input               s_axis_ip_valid             ,
//上层数据
    output [63:0]       m_axis_user_data            ,
    output [31:0]       m_axis_user_user            ,
    output [7 :0]       m_axis_user_keep            ,
    output              m_axis_user_last            ,
    output              m_axis_user_valid           
);

reg  [15:0]             ri_set_source_port          ;
reg  [15:0]             ri_set_target_port          ;
reg  [63:0]             rs_axis_ip_data             ;
reg  [54:0]             rs_axis_ip_user             ;
reg  [7 :0]             rs_axis_ip_keep             ;
reg                     rs_axis_ip_last             ;
reg                     rs_axis_ip_valid            ;
reg  [63:0]             rm_axis_user_data           ;
reg  [31:0]             rm_axis_user_user           ;
reg  [7 :0]             rm_axis_user_keep           ;
reg                     rm_axis_user_last           ;
reg                     rm_axis_user_valid          ;
reg  [15:0]             r_cnt                       ;
reg  [15:0]             r_source_port               ;
reg  [15:0]             r_target_port               ;
reg  [15:0]             r_len                       ;
reg  [7 :0]             r_last_keep                 ;   
reg                     r_udp_flag                  ;
reg                     r_port_check                ;

assign m_axis_user_data  = rm_axis_user_data        ;
assign m_axis_user_user  = rm_axis_user_user        ;
assign m_axis_user_keep  = rm_axis_user_keep        ;
assign m_axis_user_last  = rm_axis_user_last        ;
assign m_axis_user_valid = rm_axis_user_valid       ;

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst) begin
        rs_axis_ip_data  <= 'd0;
        rs_axis_ip_user  <= 'd0;
        rs_axis_ip_keep  <= 'd0;
        rs_axis_ip_last  <= 'd0;
        rs_axis_ip_valid <= 'd0;
    end else begin
        rs_axis_ip_data  <= s_axis_ip_data ;
        rs_axis_ip_user  <= s_axis_ip_user ;
        rs_axis_ip_keep  <= s_axis_ip_keep ;
        rs_axis_ip_last  <= s_axis_ip_last ;
        rs_axis_ip_valid <= s_axis_ip_valid;
    end    
end
//动态配置端口号
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        ri_set_source_port <= P_SOURCE_PORT;
    else if(i_set_source_valid)
        ri_set_source_port <= i_set_source_port;
    else 
        ri_set_source_port <= ri_set_source_port;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        ri_set_target_port <= 'd0;
    else if(i_set_target_valid)
        ri_set_target_port <= i_set_target_port;
    else 
        ri_set_target_port <= ri_set_target_port;
end
//保存最后一次的Keep信号
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_last_keep <= 'd0;
    else if(s_axis_ip_last)
        r_last_keep <= s_axis_ip_keep;
    else 
        r_last_keep <= 8'b1111_1111;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_cnt <= 'd0;
    else if(rs_axis_ip_valid)
        r_cnt <= r_cnt + 1;
    else 
        r_cnt <= 'd0;
end
//获取IP层传递过来的数据的源端口号
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_source_port <= 'd0;
    else if(rs_axis_ip_valid && r_cnt == 0)
        r_source_port <= rs_axis_ip_data[63:48];
    else 
        r_source_port <= r_source_port;
end
//获取IP层传递过来的数据的目的端口号
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_target_port <= 'd0;
    else if(rs_axis_ip_valid && r_cnt == 0)
        r_target_port <= rs_axis_ip_data[47:32];
    else 
        r_target_port <= r_target_port;
end
//检测获取的源端口号是否等于本节点的目的端口号
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_port_check <= 'd0;
    else if(r_cnt == 1 && r_target_port != ri_set_source_port)       
        r_port_check <= 'd0;
    else if(r_cnt == 1 && r_target_port == ri_set_source_port)
        r_port_check <= 'd1;
    else 
        r_port_check <= r_port_check;
end
//获取数据净荷的长度
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        r_len <= 'd0;
    else if(rs_axis_ip_valid && r_cnt == 0)
        r_len <= rs_axis_ip_data[31:16] - 16'd8;
    else 
        r_len <= r_len;
end

always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        rm_axis_user_data <= 'd0;
    else
        rm_axis_user_data <= rs_axis_ip_data;
end
//控制向上传递的USER信号,其中r_len代表字节长度,(r_len - 16'd1) >> 16'd3代表以8字节为单位的传输次数
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        rm_axis_user_user <= 'd0;
    else 
        rm_axis_user_user <= {r_len,((r_len - 16'd1) >> 16'd3) + 16'd1};
end 
//控制keep信号
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)
        rm_axis_user_keep <= 'd0;
    else if(rs_axis_ip_last)
        rm_axis_user_keep <= r_last_keep;
    else 
        rm_axis_user_keep <= 8'b1111_1111;
end
//控制Last信号
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)   
        rm_axis_user_last <= 'd0;
    else if(rs_axis_ip_last && rm_axis_user_valid)
        rm_axis_user_last <= 'd1;
    else 
        rm_axis_user_last <= 'd0;
end
//控制Valid信号
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)  
        rm_axis_user_valid <= 'd0;
    else if(rm_axis_user_last)
        rm_axis_user_valid <= 'd0;
    else if(rs_axis_ip_valid && r_cnt == 1 && r_port_check && r_udp_flag)
        rm_axis_user_valid <= 'd1;
    else 
        rm_axis_user_valid <= rm_axis_user_valid;
end
//检查本次从IP层获取的信号是否为UDP数据
always@(posedge i_clk,posedge i_rst)
begin
    if(i_rst)  
        r_udp_flag <= 'd0;
    else if(s_axis_ip_valid && !rs_axis_ip_valid && s_axis_ip_user[36:29] != 17)
        r_udp_flag <= 'd0;
    else if(s_axis_ip_valid && !rs_axis_ip_valid && s_axis_ip_user[36:29] == 17)
        r_udp_flag <= 'd1;
    else 
        r_udp_flag <= r_udp_flag;
end

endmodule

三、仿真

UDP_TX模块:

UDP_RX模块:

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot3笔记(一)SpringBoot3-核心特性

快速学习 SpringBoot 看官方文档&#xff1a; Spring Boot Reference Documentation 计划三天学完 笔记&#xff1a;https://www.yuque.com/leifengyang/springboot3 代码&#xff1a;https://gitee.com/leifengyang/spring-boot-3 一、SpringBoot3 - 快速入门 1.1 简介 …

【设计模式】——装饰模式(包装器模式)

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

跨境选品师不是神话:普通人也能轻松掌握,开启全球贸易新篇章!

随着互联网技术的飞速发展&#xff0c;跨境电商行业已成为全球经济的新增长点。在这个背景下&#xff0c;一个新兴的职业——跨境选品师&#xff0c;逐渐走进了人们的视野。那么&#xff0c;跨境选品师究竟是做什么的?普通人又该如何成为优秀的跨境选品师呢? 一、跨境选品师的…

搭建CMS系统

搭建CMS系统 1 介绍 内容管理系统&#xff08;Content Management System&#xff0c;CMS&#xff09;是一种用于管理、发布和修改网站内容的系统。开源的CMS系统有WordPress、帝国CMS等&#xff0c;国产的Halo很不错。 WordPress参考地址 # 官网 https://wordpress.org/# …

C# 机构仿真实例

1、实现连杆带动滑块运动 一个连杆旋转带动另一个连杆&#xff0c;另一个连杆拖动滑块&#xff0c;点击“开始”按钮开始运动&#xff0c;再点击按钮&#xff0c;则停止运动。 2、实现程序 #region 机构仿真Image image null;Timer timer new Timer();int width 0;int heig…

Rust面试宝典第14题:旋转数组

题目 给定一个数组&#xff0c;将数组中的元素向右移动k个位置&#xff0c;其中k是非负数。要求如下&#xff1a; &#xff08;1&#xff09;尽可能想出更多的解决方案&#xff0c;至少有三种不同的方法可以解决这个问题。 &#xff08;2&#xff09;使用时间复杂度为O(n)和空间…

Python中Web开发-FastAPI框架

大家好&#xff0c;在当今Web开发领域&#xff0c;高性能、易用性和可扩展性是开发者们追求的目标。Python作为一种流行的编程语言&#xff0c;在Web开发领域也有着强大的影响力。而在众多的Python Web框架中&#xff0c;FastAPI凭借其快速、现代和易用的特性&#xff0c;成为了…

Android Graphics 显示系统 - Android 14(U)编译/运行Surface绘图、多屏同显/异显示例

1 前言 近来&#xff0c;有粉丝朋友反馈早前提供的演示demo在Android 14平台上编译有问题&#xff0c;想询问该怎么修改适配。最近一直很忙也就没顾得上处理这些问题&#xff0c;这几天得空就来移植一下吧。 早前我们的demo和讲解都是基于Android 12展开的&#xff0c;本质大…

【C++】二叉树进阶(二叉搜索树)

目录 一、内容安排说明二、 二叉搜索树2.1 二叉搜索树概念2.2 二叉搜索树操作2.2.1 二叉搜索树的查找2.2.2 二叉搜索树的插入2.2.3 二叉搜索树的删除 2.3 二叉搜索树的代码实现2.3.1 二叉搜索树的节点设置2.3.2 二叉搜索树类的框架2.3.3 二叉搜索树的查找函数2.3.3.1 非递归方式…

跨平台之用VisualStudio开发APK嵌入OpenCV(二)

开始干 新建解决方案&#xff0c;新建动态库&#xff08;Android&#xff09;项目 功能随便选一个吧&#xff0c;就模仿PS&#xff08;Photoshop&#xff09;的透视裁切功能&#xff0c;一个物体&#xff08;比如扑克牌&#xff09;透视图&#xff0c;选4个顶点&#xff0c;转…

2000 年至 2015 年中国(即水稻、小麦和玉米1km 网格)三种主要作物年收获面积的时空变化

摘要 可靠、连续的主要作物收获面积信息对于研究地表动态和制定影响农业生产、土地利用和可持续发展的政策至关重要。然而&#xff0c;中国目前还没有高分辨率的空间明确和时间连续的作物收获面积信息。全国范围内主要农作物收获面积的时空格局也鲜有研究。在本研究中&#xf…

【深度学习】第1章

概论: 机器学习是对研究问题进行模型假设,利用计算机从训练数据中学习得到模型参数,并最终对数据进行预测和分析,其基础主要是归纳和统计。 深度学习是一种实现机器学习的技术,是机器学习重要的分支。其源于人工神经网络的研究。深度学习的模型结构是一种含多隐层的神经…

长安链使用Golang编写智能合约教程(一)

编写前的注意事项&#xff1a; 1、运行一条带有Doker_GoVM的链 2、建议直接用官方的在线IDE去写合约&#xff0c;因为写完可以直接测&#xff0c;缺点只是调试不方便。 3、自己拉环境在本地写合约&#xff0c;编译时注意编译环境&#xff0c;官方有提醒你去Linux下去编译。 …

【2024.5.26 软件设计师】记录第一次参加软考(附资料)

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux &#x1f618;欢迎 ❤️关注 &#x1f44d;点赞 &#x1f64c;收藏 ✍️留言 文章目录 前言考试分析选择题案例分析题话外 软考总结资料 前言 这是我第一次参加软考&#xff0c;其实我并…

到底该用英文括号还是中文括号?

这篇博客写的还挺详细的&#xff0c;不错。

如何使用多种算法解决LeetCode第135题——分发糖果问题

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…

美甲店会员预约系统管理小程序的作用是什么

女性爱美体现在方方面面&#xff0c;美丽好看的指甲也不能少&#xff0c;市场中美甲店、小摊不少&#xff0c;也跑出了不少连锁品牌&#xff0c;70后到00后&#xff0c;每个层级都有不少潜在客户&#xff0c;商家需要获取和完善转化路径&#xff0c;不断提高品牌影响力与自身内…

【图解IO与Netty系列】IO的同步与异步、阻塞与非阻塞,Linux五种IO模型

IO的同步与异步、阻塞与非阻塞&#xff0c;Linux五种IO模型 IO的同步与异步&#xff0c;阻塞与非阻塞阻塞IO与非阻塞IO同步IO与异步IO Linux五种IO模型BIONIOIO多路复用信号驱动IOAIO IO的同步与异步&#xff0c;阻塞与非阻塞 我们有时会看到类似于同步阻塞式IO、同步非阻塞式…

【二叉树算法题记录】236. 二叉树的最近公共祖先

题目链接 题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个…