学习NET-SNMP之一---------编译NET-SNMP程序。

    xiaoxiao2021-03-25  217

    该程序摘自《深入理解NET-SNMP实战》第8章的示例程序,编译本书代码的前提是已经从NET-SNMP源码编译出lib文件。

    同事有完整的源代码文件。

    一、程序源代码

    #include<net-snmp/net-snmp-config.h> #include<net-snmp/includes.h> #include<string.h> int main(int argc,char *argv) { /* 结构体netsnmp_session中记录了SNMP会话信息; 第一个变量需要填充准备会话的信息, 第二个为一指针用于记录返回的会话信息; */ netsnmp_session session,*ss; netsnmp_pdu *pdu;//该结构体中记录了远程主机所有的信息。 netsnmp_pdu *response;//该结构体中记录了远程主机返回的PDU信息。 //记录OID节点位置信息 oid anOID[MAX_OID_LEN]; size_t anOID_len; //变量绑定列表(为list数据结构),也就是需要操作的数据。 netsnmp_variable_list *vars; int status; int count=1; /* 初始化SNMP库; 初始化互斥量、MIB解析、传输层、 调试信息的初始化、解析配置文件的初始化(netsnmp_ds_register_config),各种句柄的初始化。 定时器的初始化、读取配置文件 */ init_snmp("snmpdemoapp"); /* session的初始化:包括初始化目的地,SNMP协议版本、认证机制、初始化会话结构体(为默认值),不是及任何的MIB文件处理。 */ snmp_sess_init(&session); //设置会话结构体:目标地址;可以为其他有效的网络地址 session.peername=strdup("localhost"); //使用SNMPv1版本 session.version=SNMP_VERSION_1; //设置共同体 session.community="public"; session.community_len=strlen(session.community); /* 开启和绑定底层的传输层(TCP/UDP),建立会话,返回会话句柄,每个会话对应一个socket */ ss=snmp_open(&session); if(!ss){ snmp_sess_perror("snmpdemoapp",&session); exit(1); } /* 会话创建完成后,接下来是创建指定类型(命令类型)的PDU,作为本次会话的实例执行操作的准备, 这就包括绑定准备通信的OID */ pdu=snmp_pdu_create(SNMP_MSG_GET); anOID_len=MAX_OID_LEN;//该宏值为128,正如RFC建议所述“节点下子OID数量不超过128个”。 /* 此处read_objid / snmp_parse_oid的作用是检查OID的正确性, 兵赋予anOID正确的值,也就是最终请求的OID */ //read_objid("system.sysDescr.0", anOID, &anOID_len); //if ( !snmp_parse_oid(".1.3.6.1.2.1.1.1.0",anOID, &anO_len)){ if(!snmp_parse_oid("system.sysDescr.0",anOID,&anOID_len)){ snmp_perror(".1.3.6.1.2.1.1.1.0"); exit(1); } /* 按照协议PDU格式的要求,将该OID加入到PDU报文中, 同时赋予一个NULL值作为变量的绑定; 当然对于SET命令的PDU来说就是赋予待设置的值。 */ snmp_add_null_var(pdu,anOID,anOID_len); //同步发送报文。 status = snmp_synch_response(ss,pdu,&response); /* 下面的代码是处理返回的PDU报文,需要根据返回的信息作出合理的后续处理: 报文的返回和执行状态都正确,读取返回的值。 */ if( status == STAT_SUCCESS && response->errstat ==SNMP_ERR_NOERROR){ //将读取的返回值打印到标准输出(stdout)出来。 for(vars=response->variables;vars;vars=vars->next_variable) print_variable( vars->name, vars->name_length,vars );//处理(打印)接收到的信息; for(vars=response->variables;vars;vars=vars->next_variable) { if(vars->type==ASN_OCTET_STR){ char *sp = (char *)malloc(1 + vars->val_len); memcpy(sp,vars->val.string,vars->val_len); sp[vars->val_len]='\0'; printf("value #%d is a string :%s\n", count++,sp); free(sp); }else{ //如果返回值有错误:打印其错误信息 printf("value #%d is NOT a string! Ack\n",count++); } } }else{ if(status == STAT_SUCCESS) fprintf(stderr,"Error in packet\nReason: %s\n",snmp_errstring(response->errstat)); else if(status == STAT_TIMEOUT) fprintf(stderr,"Timeout: No response from %s. \n",session.peername); else snmp_sess_perror("snmpdemoapp",ss); } //释放分配的空间:关闭会话,关闭socket,释放资源。 if(response) snmp_free_pdu(response); snmp_close(ss); return(0); }

    二、程序编译的环境

    1.IDE: VisualStudio2010

    2. SNMP库版本:net-snmp 5.7.3

    3.新建Win32控制台空项目(选择预先编译头文件)

    4.新建CPP源文件并拷贝以上源文件。

    三、编译过程产生的问题。

    问题一:找不到头文件和netsnmp_session。

    解决方法:

    1.添加头文件目录(C/C++  |  常规  |   附加包含目录 )

    net-snmp-5.7.3 \ win32

    net-snmp-5.7.3 \ include

    2.修改原本包含的头文件(因为对应的版本文件名改变了)

    将#include <net-snmp/ includes.h >修改为 #include< net-snmp / net-snmp-includes.h >

    问题二:error C2440: “=”: 无法从“const char [7]”转换为“u_char *”

    解决方法:

    session.community="public";

    session.community_len=strlen(session.community);

    修改为:

    session.community=(u_char *)"public";

    session.community_len=strlen( (char*) session.community);

    问题三:fatal error LNK1120: 13 个无法解析的外部命令

    fatal error LNK1120: 26 个无法解析的外部命令

    解决方法:

    1.添加库目录(链接器 |   常规  |   附加库目录)

    目录选择生成的链接库所在的目录。

    2.添加链接库文件(以下使用宏处理命令方式添加)

    #pragma comment (lib,"netsnmp.lib") #pragma comment (lib, "ws2_32.lib")

    第一个库针对13个无法解析的命令。

    第二个库针对26个无法解析的命令。

    转载请注明原文地址: https://ju.6miu.com/read-3373.html

    最新回复(0)