SNMP(简单网络管理协议)详解

2023-05-16

一、简介

SNMP(简单网络管理协议): 专门用于在 IP 网络管理网络节点(服务器、工作站、路由器、交换机及HUBS等)的一种标准协议,它是一种应用层协议。 SNMP 使网络管理员能够管理网络效能,发现并解决网络问题以及规划网络增长。通过 SNMP 接收随机消息(及事件报告)网络管理系统获知网络出现问题。

SNMP的前身是简单网关监控协议(SGMP),用来对通信线路进行管理。随后,人们对SGMP进行了很大的修改,特别是加入了符合Internet定义的SMI和MIB,改进后的协议就是著名的SNMP。

  • 管理信息结构SMI(Structure ofManagement Information)定义了SNMP框架所用信息的组织和标识,为MIB定义管理对象及使用管理对象提供模板。
  • 管理信息库MIB(,Management Information Base定义了可以通过SNMP进行访问的管理对象的集合,一种树状数据库,MIB管理的对象,就是树的端节点。
  • 对象识别符OID(Object Identifier)定义了端节点的唯一位置和唯一名字,其命名规则就是父节点的名字作为子节点名字的前缀。 

二、架构原理

 一个SNMP管理的网络由下列三个关键组件组成:

  • 网络管理系统(NMS,Network-management systems)NMS运行应用程序,监控被管理的设备。网络管理系统提供网络管理需要的大量运算和记忆资源。
  • 被管理的设备(managed device)被管理的设备是一个网络节点,它包含一个SNMP agent。被管理的设备通过管理信息库(MIB)收集并存储管理信息,并且让网络管理系统通过agent读取这些信息。
  • 代理者(agent)agent是一种存在于被管理的设备中的网络管理软件模块。agent控制本地机器的管理信息,以和SNMP兼容的格式传送这项信息。

主代理是一个在可运行的SNMP网络组件上运作的软件,可回应从管理站发出的SNMP要求。它的角色类似C/S术语中的服务器。主代理依赖子代理提供有关特定功能的管理信息。

子代理是一个在可运行的SNMP网络组件上运作的软件,运行在特定子系统的特定管理信息库(MIB,Management Information Base)中定义的信息和管理功能。子代理的一些能力有:搜集主代理的信息、配置主代理的参数、回应管理者的要求、产生警告或陷阱trap

主代理和子代理的角色可以合并,在这种情况下我们可以简单的称之为代理(agent)。

​SNMP定义了五种Manager与Agent之间的通讯形式。

  1. Get-request
  2. Get-next-request
  3. Set-request
  4. Get-response
  5. Trap

前三项都是属于Manager向Agent发出的讯息,后两项则属于Agent向Manager发出的讯息

Trap:当设备发生了各种事件之后,产生的MIB信息由SNMP代理主动向NMS发送,是不需要NMS请求的,NMS收到之后不需要向SNMP代理发送确认消息,SNMP发出去的Trap是根本不知道NMS是否收到,自己发送完毕之后,这些MIB信息会马上删除,不会驻留内存里面。

informs:informs和Trap恰好相反、设备发生事件后,这些信息并不会主动向NMS通告,除非NMS发送requst来查询,然后才会发出去,但是发出去的informs之后会保留在内存里面,当NMS收到informs之后必须向SNMP代理发送确认消息,如果不发送确认消息,SNMP代理会重复多次发送informs(informs具有可靠性)

通过NMS来更改设备上的配置,查询设备信息,发送的数据包为Get,更改设备的配置为Set

三、现存版本

  • SNMPV1:该版本基于简单网关监视协议发展而来的,于1988年发布,安全性差,错误状态较少。典型的,SNMP为代理使用UDP端口161,为管理站使用UDP端口162。客户端的认证使用明码传送。
  • SNMPV2SNMP v2c(基于社区的SNMP第二版)定义于RFC 1901–RFC 1908,SNMP v2u(基于用户的SNMP第二版)定义于RFC 1909–RFC 1910。由于高复杂度,产生了商业化的变种,称为SNMP v2*,而且它的机制最后被SNMP第三版的两个安全性框架之一采用。
  • SNMPV3:Internet工程工作小组(IETF)把在RFC3411-RFC3418(STD0062)中定义的SNMP第三版作为2004年的标准版本,以替代SNMPV1正式成为标准协议,SNMP第三版提供三项重要的服务:认证、隐私和访问控制。

四、技术优点

SNMP是管理进程(NMS)和代理进程(Agent)之间的通信协议。它规定了在网络环境中对设备进行监视和管理的标准化管理框架、通信的公共语言、相应的安全和访问控制机制。网络管理员使用SNMP功能可以查询设备信息、修改设备的参数值、监控设备状态、自动发现网络故障、生成报告等。

SNMP具有以下技术优点:

  1. 基于TCP/IP互联网的标准协议,传输层协议一般采用UDP。
  2. 自动化网络管理。网络管理员可以利用SNMP平台在网络上的节点检索信息、修改信息、发现故障、完成故障诊断、进行容量规划和生成报告。
  3. 屏蔽不同设备的物理差异,实现对不同厂商产品的自动化管理。SNMP只提供最基本的功能集,使得管理任务与被管设备的物理特性和实际网络类型相对独立,从而实现对不同厂商设备的管理。
  4. 简单的请求—应答方式和主动通告方式相结合,并有超时和重传机制。
  5. 报文种类少,报文格式简单,方便解析,易于实现。
  6. SNMPv3版本提供了认证和加密安全机制,以及基于用户和视图的访问控制功能,增强了安全性。

五、snmp4j代码示例

先看一下SNMP协议要传输的内容:SNMP的5种协议数据单元_协议分析网

接下来就是用SNMP4J协议的jar包来完成各个功能:http://www.snmp4j.org/html/download.html

SNMP4J把开发包分为了两个,一个SNMP4J.jar主要负责get,trap,set,一个是SNMP4J-Agent.jar主要负责作为一个网元被管理。

5.1、开发一个Agent

 需要用到两个配置文件bc和cfg文件,可以在这里下载:http://download.csdn.net/detail/three_man/7477991

import java.io.File;  
import java.io.IOException;  
import java.util.ArrayList;  
import java.util.List;  
import org.snmp4j.agent.BaseAgent;  
import org.snmp4j.agent.CommandProcessor;  
import org.snmp4j.agent.DuplicateRegistrationException;  
import org.snmp4j.agent.io.ImportModes;  
import org.snmp4j.agent.mo.DefaultMOTable;  
import org.snmp4j.agent.mo.MOTableRow;  
import org.snmp4j.agent.mo.snmp.RowStatus;  
import org.snmp4j.agent.mo.snmp.SnmpCommunityMIB;  
import org.snmp4j.agent.mo.snmp.SnmpNotificationMIB;  
import org.snmp4j.agent.mo.snmp.SnmpTargetMIB;  
import org.snmp4j.agent.mo.snmp.StorageType;  
import org.snmp4j.agent.mo.snmp.VacmMIB;  
import org.snmp4j.agent.security.MutableVACM;  
import org.snmp4j.mp.MPv3;  
import org.snmp4j.security.SecurityLevel;  
import org.snmp4j.security.SecurityModel;  
import org.snmp4j.security.USM;  
import org.snmp4j.smi.Integer32;  
import org.snmp4j.smi.OID;  
import org.snmp4j.smi.OctetString;  
import org.snmp4j.smi.Variable;  
  
public class MyAgent extends BaseAgent {  
    private List<DefaultMOTable> moTables = new ArrayList<DefaultMOTable>();  
    private String community;  
      
    protected MyAgent(File bootCounterFile, File configFile, List<DefaultMOTable> moTables, String community) {  
        super(bootCounterFile, configFile, new CommandProcessor(new OctetString(MPv3.createLocalEngineID())));  
        this.moTables = moTables;  
        this.community = community;  
    }  
      
    @Override  
    protected void registerManagedObjects() {  
        try {  
            for (DefaultMOTable table : moTables) {  
                server.register(table, null);  
            }  
        } catch (DuplicateRegistrationException e) {  
            e.printStackTrace();  
        }  
    }  
      
    public void startUp(){  
        try {  
            this.init();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        this.loadConfig(ImportModes.REPLACE_CREATE);  
        this.addShutdownHook();  
        this.getServer().addContext(new OctetString(community));  
        this.finishInit();  
        this.run();  
        this.sendColdStartNotification();  
    }  
      
    /** 
     * to set community 
     */  
    @Override  
    protected void addCommunities(SnmpCommunityMIB communityMIB) {  
        Variable[] com2sec = new Variable[] {  
                new OctetString(community),                     // community name  
                new OctetString("cpublic"),                 // security name  
                getAgent().getContextEngineID(),            // local engine ID  
                new OctetString(community),                     // default context name  
                new OctetString(),                          // transport tag  
                new Integer32(StorageType.nonVolatile),     // storage type  
                new Integer32(RowStatus.active)             // row status  
        };  
        MOTableRow row =  
            communityMIB.getSnmpCommunityEntry().createRow(  
                    new OctetString("public2public").toSubIndex(true), com2sec);  
        communityMIB.getSnmpCommunityEntry().addRow(row);  
  
    }  
} 
  •  主要的代码是需要继承BaseAgent
  • 需要设置community
  • 需要注册Table,这个注册中的内容将是供给get和walk的内容。
  • 可以从MIB直接构建Agent,可能需要的包为:mibble-mibs是能够独MIB结构。这个也提供个下载地址吧: http://download.csdn.net/detail/three_man/7478061

5.2、Trap Receiver

import java.io.IOException;  
import java.util.logging.Logger;  
import org.snmp4j.MessageDispatcherImpl;  
import org.snmp4j.Snmp;  
import org.snmp4j.TransportMapping;  
import org.snmp4j.mp.MPv2c;  
import org.snmp4j.smi.Address;  
import org.snmp4j.smi.GenericAddress;  
import org.snmp4j.smi.UdpAddress;  
import org.snmp4j.transport.DefaultUdpTransportMapping;  
import org.snmp4j.util.MultiThreadedMessageDispatcher;  
import org.snmp4j.util.ThreadPool;  
import com.prince.snmp.tool.Command;  
import com.prince.snmp.tool.util.Configure;  
import com.prince.snmp.tool.util.Const;  
  
/** 
 * 构建一个多线程的Trap Receiver 
 * @author wangzijian 
 * 
 */  
public class SnmpReceiver implements Command{  
    private final Logger log = Logger.getLogger(SnmpReceiver.class.getName());  
  
    @Override  
    public void startUp() throws IOException {  
        log.info("Snmp Trap Receiver Start");  
        log.info("listened on " + Configure.getInstance().getUdpTrapIpPort());  
        ThreadPool pool = ThreadPool.create(Const.THREAD_POOL_NAME, Const.AGENT_THREAD_NUM);  
        MultiThreadedMessageDispatcher dispatcher = new MultiThreadedMessageDispatcher(pool, new MessageDispatcherImpl());  
        Address listenAddress = GenericAddress.parse(Configure.getInstance().getUdpTrapIpPort());  
        TransportMapping transport = new DefaultUdpTransportMapping((UdpAddress) listenAddress);  
        // 构建SNMP,并且使其开始监听  
        Snmp snmp = new Snmp(dispatcher, transport);  
        snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());  
        snmp.listen();  
        snmp.addCommandResponder(new CommandResponderImpl());  
    }  
}  


package com.prince.snmp.tool.receiver;  
  
import java.util.List;  
import java.util.logging.Logger;  
import org.snmp4j.CommandResponder;  
import org.snmp4j.CommandResponderEvent;  
import org.snmp4j.PDU;  
import org.snmp4j.smi.OID;  
import org.snmp4j.smi.VariableBinding;  
  
public class CommandResponderImpl implements CommandResponder {  
    private final Logger log = Logger.getLogger(CommandResponderImpl.class.getName());  
      
    @Override  
    public void processPdu(CommandResponderEvent event) {  
        PDU pdu = event.getPDU();  
        if(PDU.TRAP == pdu.getType()){  
            operate(pdu);  
        }else{  
            log.info("pdu method is:" + pdu.getType() + " not a trap");  
        }  
          
    }  
  
    private void operate(PDU pdu) {  
        List<VariableBinding> bindings = pdu.getBindingList(new OID(".1"));  
          
        for (VariableBinding binding : bindings) {  
            System.out.println(binding.getOid() + "====" + binding.getVariable().toString());  
        }  
    }  
}  
  •  需要一个多线程的服务器MultiThreadedMessageDispatcher
  • 还需要一个处理类 CommandResponderImpl  snmp.addCommandResponder
  • 在处理类中能够得到PDU,这个类不只可以作为Receiver还能够开发为Agent,但是需要自己来写很多逻辑,还有可能用到文件或者内存数据库

5.3、send trap

package com.prince.snmp.tool.trap;  
  
import java.io.IOException;  
import java.lang.reflect.InvocationTargetException;  
import java.util.List;  
import java.util.Vector;  
import org.snmp4j.CommunityTarget;  
import org.snmp4j.PDU;  
import org.snmp4j.Snmp;  
import org.snmp4j.TransportMapping;  
import org.snmp4j.event.ResponseEvent;  
import org.snmp4j.smi.Address;  
import org.snmp4j.smi.GenericAddress;  
import org.snmp4j.smi.OctetString;  
import org.snmp4j.smi.UdpAddress;  
import org.snmp4j.smi.VariableBinding;  
import org.snmp4j.transport.DefaultUdpTransportMapping;  
import com.prince.snmp.tool.Command;  
import com.prince.snmp.tool.trap.dataGenerator.ITrapGenerator;  
import com.prince.snmp.tool.util.Configure;  
  
public class TrapSender implements Command{  
    private Snmp snmp;  
    private Address targetAddress;  
    private ITrapGenerator generator;  
      
    public TrapSender(ITrapGenerator generator) {  
        this.generator = generator;  
        targetAddress = GenericAddress.parse(Configure.getInstance().getUdpTrapIpPort());  
        TransportMapping<UdpAddress> transport = null;  
        try {  
            transport = new DefaultUdpTransportMapping();  
            snmp = new Snmp(transport);  
            transport.listen();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
      
    public void sendTrap(){  
        CommunityTarget target = new CommunityTarget();  
        target.setAddress(targetAddress);  
        target.setRetries(Configure.getInstance().getRetries());  
        target.setTimeout(Configure.getInstance().getTimeOut());  
        target.setCommunity(new OctetString(Configure.getInstance().getCommunity()));  
        target.setVersion(Configure.getInstance().getSnmpVersion());  
          
        List<TrapData> datas = generator.generateTrapData();  
          
        try {  
            for (TrapData trapData : datas) {  
                sendPdu(trapData, target);  
            }  
        } catch (IllegalAccessException e) {  
            e.printStackTrace();  
        } catch (InvocationTargetException e) {  
            e.printStackTrace();  
        } catch (NoSuchMethodException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
      
    private void sendPdu(TrapData trapData, CommunityTarget target) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, IOException {  
        PDU pdu = MoToPdu.moToPdu(trapData);  
        ResponseEvent respEvnt = snmp.send(pdu, target);  
          
        // 解析Response    
        if (respEvnt != null && respEvnt.getResponse() != null) {    
            Vector<VariableBinding> recVBs = (Vector<VariableBinding>) respEvnt.getResponse().getVariableBindings();    
            for (int i = 0; i < recVBs.size(); i++) {    
                VariableBinding recVB = recVBs.elementAt(i);    
                System.out.println(recVB.getOid() + " : " + recVB.getVariable());    
            }    
        }  
    }  
  
      
}  
  •   trap主要注意必须设置两个VariableBingding

                pdu.add(new VariableBinding(SnmpConstants.sysUpTime, new TimeTicks(trap.getSysUpTime())));

                pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OID(trap.getTrapOid())))

5.4、get

private static void simpleGet() throws IOException {  
    TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();  
    Snmp snmp = new Snmp(transport);  
    transport.listen();  
      
    CommunityTarget target = new CommunityTarget();   
    target.setCommunity(new OctetString("CONV"));  
    Address targetAddress = GenericAddress.parse("udp:10.141.43.237/161");   
    target.setAddress(targetAddress);  
    target.setRetries(3);  
    target.setTimeout(3000);  
    target.setVersion(SnmpConstants.version2c);  
      
    PDU pdu = new PDU();    
       pdu.add(new VariableBinding(new OID(".1.3.6.1.4.1.7569.1.2.1.23.3.1")));    
       pdu.setType(PDU.GETBULK);  
       pdu.setMaxRepetitions(20);  
       pdu.setNonRepeaters(0);  
         
       ResponseEvent respEvnt = snmp.send(pdu, target);    
       if (respEvnt != null && respEvnt.getResponse() != null) {    
              Vector<VariableBinding> recVBs = (Vector<VariableBinding>) respEvnt.getResponse().getVariableBindings();    
              for (int i = 0; i < recVBs.size(); i++) {    
                     VariableBinding recVB = recVBs.elementAt(i);    
                     System.out.println(recVB.getOid() + " : " + recVB.getVariable());    
  
              }    
  
       }    
}  
  •  get相对于比较简单,资料也比较多。主要是设定pdu.setType(PDU.GETBULK);
  • 利用getnext和一些判断可以实现walk.
  • http://blog .sina.com.cn/s/blog_6cb15f8f0100yx4p.html 这个哥们儿写得非常好

具体的代码没有写,因为下一篇会共享一个小的工具,可以以配置文件为基础来构建Receiver,发送Trap,构建Agent等。

六、附录

具体参考:阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台

简单网络管理协议SNMP(史上最全)_奇妙之二进制的博客-CSDN博客_snmp是什么协议

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SNMP(简单网络管理协议)详解 的相关文章

  • docker 授权给普通用户

    目录 docker 授权给普通用户 给普通用户增加docker命令的权限给普通用户增加启动和关闭docker的权限 docker 授权给普通用户 给普通用户增加docker命令的权限 我们用命令可以看出docker下的属主属组都是root
  • APM飞控学习之路:1 无人机的分类与发展

    旧时王谢堂前燕 xff0c 飞入寻常百姓家 无人机也像那堂前燕 xff0c 从以前为军事所专属 xff0c 负责侦查和战斗 xff0c 飞入民用领域 xff0c 在航拍 植保 快递 救灾 巡检 拍摄等行业大显身手 xff0c 无人机 43
  • STM32 HAL库串口回调机制详解

    在开始学习STM32的时候 xff0c 会发现 xff0c 怎么有个串口中断回调和串口中断不一样的概念啊 xff0c 感觉很头晕 xff0c 找了很久也没发现到底区别在哪儿 xff0c 回调机制是怎么实现的 下面就详解一下 xff1a 通过
  • printf重定向问题

    我用的STM32型号为STM32F100VBT6B 重定向方法一 xff1a ifdef GNUC With GCC RAISONANCE small printf option LD Linker gt Libraries gt Smal
  • 流媒体服务器原理和架构解析

    原文 xff1a https blog csdn net xuheazx article details 52020933 一个完整的多媒体文件是由音频和视频两部分组成的 xff0c H264 Xvid等就是视频编码格式 xff0c MP3
  • SBUS协议学习

    目录 文章目录 目录摘要1 什么是SBUS协议2 STM32 解析 SBUS协议2 1初始化串口接收2 2配置串口中断服务函数2 3进行SBUS数据解析2 4在任务中调用2 5相关变量和定义 3 获取数据 摘要 本节主要记录自己学习SBUS
  • ardupilot EKF2速度位置融合算法

    目录 文章目录 目录摘要1 更新滤波器2 使用GPS和测距仪更新EKF2的速度 xff0c 位置信息1 高度融合算法2 进行高度估计 摘要 本节主要记录自己看EKF2的速度位置融合算法 1 更新滤波器 span class token ke
  • C#学习之-------mp地面站 Mavlink Demo代码学习《0》

    目录 文章目录 目录摘要1 代码路径2 打开代码3 运行代码4 代码分析1 应用程序入口2 程序simpleexample 摘要 本节主要记录自己学习ardupilot的地面站MP代码Mavlink协议的官网Demo过程 1 代码路径 代码
  • ardupilot 上实现ADRC内环角速度控制

    目录 文章目录 目录 摘要 0 写之前 1 关键参考公式 1 先上传一个关键的模型图 2 用到的关键公式 2 上传代码 1 非线性ADRC 2 线性ADRC 3 移植细节 4 飞行视频 5 难点 6 遗留问题 摘要 本节主要记录自己在ard
  • ardupilot 日志分析《xKF1信息》

    目录 文章目录 目录 摘要 1 xKF1信息 1 简介 2 整体代码调用流程 3 MP日志查看 2 xKF2信息 1 简介 2 整体代码调用流程 3 MP日志查看 3 xKF3信息 1 简介 2 流程 3 MP地面站数据 4 xKF4信息
  • ardupilot GPS ublox协议学习

    目录 文章目录 目录 摘要 1 UBLOX协议简介 1 协议特征 2 协议结构类型 1 有效载荷 2 校验 3 类ID 2 UBLOX专有协议 PUBX 消息 3 UBLOX常用协议 1 UBX ACK 0x05 2 UBX CFG 0X0
  • Ardupilot EKF3核心算法《状态向量》

    目录 文章目录 目录摘要1 Ardupilot 中的状态向量1 预测状态量2 输出状态量 摘要 本节主要讲解Ardupilot EKF3核心算法 状态向量 过程 1 Ardupilot 中的状态向量 1 预测状态量 Ardupilot代码中
  • Ardupilot EKF3核心算法《气压计,GPS更新融合》

    目录 文章目录 目录 摘要 1 高度融合源的选择 2 GPS的速度和位置测量序列的融合 2 1 得到GPS的观测方程 2 2 得到GPS的观测方程中的H矩阵 2 3 计算卡尔曼增益 2 2 得到GPS的测量数据 2 3 得到GPS的观测噪声
  • ardupilot 姿态误差计算分析

    目录 文章目录 目录 摘要 1 源码对比分析 1 之前代码 2 最新代码 2 结果对比 3 参考 4 结论 摘要 本节主要记录ardupilot 之前代码和最新代码姿态误差计算的核心代码分析 欢迎批评指正 1 源码对比分析 1 之前代码 2
  • Ubantu18.04 下编译PX4 环境配置

    1 用户权限准备 参考这篇博客进行 xff1a Pixhawk Ubuntu下编译原生固件PX4 外来务工人员徐某的博客 CSDN博客 2 源码的下载和子模块的更新 关于源码的下载 xff0c 由于诸多子模块的下载地址依然是github c
  • ardupilot 最优化算法

    目录 文章目录 目录 摘要 1 最小二乘法 1 1定义 1 2 基本思想 1 3 基本原理 1 4举例子 1 5最小二乘法和梯度法区别 2 梯度下降法 2 1 什么是梯度 2 2 什么是梯度下降 3 牛顿迭代法 3 0 牛顿迭代 3 1 牛
  • ardupilot 位置控制(POSHOLD)分析

    目录 文章目录 目录 摘要 0 简介 1 POSHOLD初始化过程 1 刹车增益的计算 2 位置保持不同阶段状态机对应的类型 2 POSHOLD运行过程 2 1 获取需要的飞行输入信息 2 2POSHOLD模式状态机 2 3获取当前的横滚俯
  • Ardupilot 飞控代码解锁流程分析

    摘要 本文档只有记录分析ardupilot飞控代码解锁的过程 如果有分析不到的地方 欢迎批评指导 谢谢 联系方式 18129927205 重点标志变量 flags armed 0表示没有解锁 flags armed 1表示解锁 arming
  • Ardupilot飞控Mavlink代码学习

    目录 文章目录 目录 摘要 1 Ardupilot怎么实现Mavlink初始化 2 Mavlink消息通信过程 摘要 本节主要记录自己学习Ardupilot的Mavlink协议的过程 欢迎一起交流分析 1 Ardupilot怎么实现Mavl
  • Ardupilot飞控姿态角与姿态角速度控制过程分析(超长篇)

    目录 文章目录 目录 摘要 1 自稳模式初始化 2 自稳模式更新函数 这个代码主要把横滚输入 俯仰输入量转换成目标角度需要的范围 也就是 4500 4500 3 姿态角速度代码控制过程分析 4 电机PWM控制运算 摘要 本节主要记录自己学习

随机推荐

  • PX4与Ardupilot的入门基础知识(第一章:架构与启动过程)

    目录 目录 摘要 第一节 px4与apm的区别与联系 第二节 px4与apm每个文件夹的作用 第三节 px4与apm无人机的启动过程 摘要 本节主要记录自己学px4的代码架构与Ardupilot代码架构对比文档 欢迎批评指正 1 px4与a
  • Ardupilot Pre-Arm安全检查程序分析

    目录 目录 摘要 第一 Pre Arm简介 第二 Pre Arm报错需知 1 使用前准备 使用Pre Arm信息分析不能解锁原因 2 解锁失败的原因 3 解锁失败的原因 自己对照官网进行翻译 1解锁前安全检查 2采用GCS识别是什么导致的P
  • STM32单片机汇编资料学习(1)

    目录 文章目录 目录摘要1 Cortex M3内核架构 在这里插入图片描述 https img blog csdn net 20181009223510343 watermark 2 text aHR0cHM6Ly9ibG9nLmNzZG4
  • Ardupilot 软件在环SITL仿真学习

    目录 文章目录 目录 摘要 1 配置SITL功能 2 SITL指令学习 1 如何起飞 2 如何上锁 3 如何降落 4 如何修改模式 5 如何修改遥控器输入 6 如何修改参数 摘要 本文主要学习Ardupilot 的软件在环SITL仿真功能
  • Ardupilot 串口代码学习

    目录 文章目录 目录 摘要 1 串口初始化 1 usb串口初始化 2 其他串口初始化 1 如何设置波特率和协议 2 GPS串口初始化 3 GPS数据更新 1 update instance 摘要 本节主要学习Ardupilot的串口资源代码
  • document三个方法获取对象

    主要方法 getElementById方法 span class token operator lt span span class token operator span DOCTYPE html span class token ope
  • 怎么判断c调用是内核调用还是库函数调用?

    man有如下的描述 The Linux man pages project documents the Linux kernel and C library interfaces that are employed by user prog
  • JDBC参数设置

    常用 JDBC 驱动名字和 URL 列表 ODBC driver sun jdbc odbc JdbcOdbcDriver jdbc odbc name 用 COM ibm db2 jdbc net DB2Driver 连接到 DB2 数据
  • Windows dos命令使用总结(持续更新)

    1 windows如何通过CMD命令结束某个端口的进程 xff1a netstat ano findstr 端口号tasklist findstr 进程PIDtaskkill PID 进程PID F windows常用命令 可可西 博客园
  • postgresql查询表元数据信息语句

    select tablename from pg tables where schemaname 61 39 public 39 and tablename like 39 table 39 order by tablename SELEC
  • SpringBoot 异常后更改响应状态码

    一 64 RestControllerAdvice和 64 ExceptionHandler拦截异常 package com lxk socket collector common import com lxk base bean Comm
  • linux进程kill命令关不掉

    1 Linux kill 命令用于删除执行中的程序或job 语法 xff1a kill s sigspec n signum sigspec pid jobspec or kill l sigspec kill s lt 信息名称或编号 g
  • linux tcpdump抓包命令使用详解

    一 抓包命令概述 作用 xff1a xff08 1 xff09 捕获网络协议包 xff08 2 xff09 分析网络协议包 分类 xff1a xff08 1 xff09 linux命令行工具 xff0c 如tcpdump xff08 2 x
  • wireshark抓包教程详解

    Wireshark软件安装 软件下载路径 xff1a wireshark官网 按照系统版本选择下载 xff0c 下载完成后 xff0c 按照软件提示一路Next安装 说明 xff1a 如果你是Win10系统 xff0c 安装完成后 xff0
  • docker打包流程常用方式

    完整的docker打包流程 把外网服务器上的docker搬到内网使用时 xff0c 报了两个错误 xff0c 外网容器到tar包都没问题 xff0c 在内网使用tar包的时候报了两个错误 cannot connect to the Dock
  • 5GC 网元AMF、SMF、UPF、PCF、UDM等介绍

    5GC 网元AMF SMF AUSF UPF PCF UDM NRF NSSF NEF介绍 1 AMF Access and Mobility Management Function xff0c 接入和移动性管理功能 xff0c 执行注册
  • 如何准备校招?

    秋招已经落尽尾声 xff0c 今天小牛想把自己的学习经验分享给大家 xff0c 避免大家多走弯路 1 首先需要确定自己想从事哪方面的工作 比如服务端开发 xff08 Java开发工程师 xff0c C 43 43 开发工程师 xff09 x
  • 5GC architecture N1、N2、N3、N4、N6等接口

    5GC architecture N1 N2 N3 N4 N6 N9 N26接口 N1接口 N1接口为UE和AMF间的信令面接口 N1是逻辑概念的接口 xff0c 不存在物理口 N1接口基于N2接口信令实现 N2接口 N2接口为 R AN和
  • FAQ:报红--maven本地有jar包仍从从远端下载

    问题 xff1a 最近编译项目 xff0c 发现有个模块依赖总是编译不过 xff0c 报无法download jar包 但是查看maven配置的远端仓库 xff0c 发现maven已不支持该jar包 但是本地确实存在 xff0c idea
  • SNMP(简单网络管理协议)详解

    一 简介 SNMP 简单网络管理协议 xff1a 专门用于在 IP 网络管理网络节点 xff08 服务器 工作站 路由器 交换机及HUBS等 xff09 的一种标准协议 xff0c 它是一种应用层协议 SNMP 使网络管理员能够管理网络效能