qq_28846727 2016-01-02 02:37 采纳率: 75%
浏览 1763
已结题

C++代码改成C语言代码,没学过C++好多看不懂啊(泪奔······)求大神指点,我用的VC6.0

代码如下,
#include "winsock2.h"
#include "Winsnmp.h"
#include 这里是string以下都要用 < 和 > 括起来(不知为何不显示=,=)
#include vector
#include algorithm
#include iostream
#pragma comment(lib,"wsnmp32.lib")
#pragma comment(lib,"ws2_32.lib")
using namespace std;
typedef vector strvec;
typedef vector strvec_vec;
class CManager
{public:
CManager(string strIP,string strCommunity); //构造函数
~CManager(); //析构函数
string ValueToString(smiVALUE sValue); //返回值转换
bool InitSnmp(); //用于加载SNMP
bool Send(const strvec& strOIDArray,smiINT sPDUType=SNMP_PDU_GETNEXT);
bool Receive(HSNMP_VBL& hVbl); //接收应答包
bool GetAValue(const string& strOID,string& strResult); //获取ObjectID值
bool GetTable(strvec strOIDArray,strvec_vec& strResultTable);
string GetLocalIP(); //获取本机IP地址
void ErrorMessage(string strMessage); //输出错误信息
void SetEvent();

protected:
HSNMP_SESSION m_hSession; //会话句柄
HSNMP_CONTEXT m_hContext; //上下文句柄
static SNMPAPI_STATUS CALLBACK Callback
(
HSNMP_SESSION hSession, //WinSNMP会话句柄
HWND hWnd, //处理通知窗口的句柄
UINT wMsg, //窗口消息通知码
WPARAM wParam, //消息类型
LPARAM lParam, //PDU的请求标识符
LPVOID lpClientData //可选的自定义数据
);
private:
smiUINT32 m_nMajorVersion; //WinSNMP API主版本
smiUINT32 m_nMinorVersion; //WinSNMP API副版本
smiUINT32 m_nLevel; //支持最高的操作标准
smiUINT32 m_nTranslateMode; //默认实体/上下文模式
smiUINT32 m_nRetransmitMode; //默认的重发机制
string m_IP; //IP地址
smiOCTETS m_Community; //团体名
HANDLE m_hEvent;
};
// 构造函数
CManager::CManager(string strIP,string strCommunity):
m_nMajorVersion(0),
m_nMinorVersion(0),
m_nLevel(0),
m_nTranslateMode(0),
m_nRetransmitMode(0),
m_IP(strIP)
{m_Community.len=strCommunity.length();
m_Community.ptr=new smiBYTE[strCommunity.length()];
memcpy(m_Community.ptr,strCommunity.c_str(),strCommunity.length());
m_hEvent=CreateEvent(NULL,true,false,NULL);
}

//析构函数
CManager::~CManager()
{SnmpFreeContext(m_hContext);
SnmpClose(m_hSession);
SnmpCleanup();
delete[] m_Community.ptr;
}

//SNMP初始化函数
bool CManager::InitSnmp()
{
//加载SNMP
if(SnmpStartup(&m_nMajorVersion,&m_nMinorVersion,&m_nLevel,&m_nTranslateMode,&m_nRetransmitMode)==SNMPAPI_FAILURE)
{ErrorMessage("startup SNMP error!");
return false;
}
//设置传输模式
if (SnmpSetTranslateMode(m_nTranslateMode)==SNMPAPI_FAILURE)
{ErrorMessage("Set transfer mode error!");
return false;
}
//设置重传模式
if (SnmpSetRetransmitMode(m_nRetransmitMode)==SNMPAPI_FAILURE)
{ErrorMessage("Set retransmission mode error!");
return false;
}
//建立会话
m_hSession=SnmpCreateSession(NULL,NULL,CManager::Callback,(LPVOID)this);
if(m_hSession==SNMPAPI_FAILURE)
{ErrorMessage("Set conversation error!");
return false;
}

//建立实体
HSNMP_ENTITY hEntity;
if((hEntity=SnmpStrToEntity(m_hSession,m_IP.c_str()))==SNMPAPI_FAILURE)
{ErrorMessage("Creat entity error!!");
return false;
}
//建立上下文句柄
if((m_hContext=SnmpStrToContext(m_hSession,&m_Community))==SNMPAPI_FAILURE)
{ErrorMessage("Create context handle error!!");
return false;
}
//设置超时时间
if (SnmpSetTimeout(hEntity,10)==SNMPAPI_FAILURE)
{ErrorMessage("Set timeout error!");
return false;
}
//设置重传次数
if (SnmpSetRetry(hEntity,1)==SNMPAPI_FAILURE)
{ErrorMessage("Set retransmissions error!");
return false;
}
return true;
}
//SNMP消息发送函数
bool CManager::Send(const strvec& strOIDArray,smiINT sPDUType)
{HSNMP_VBL hVbl;
HSNMP_PDU hPdu;
smiOID sOid;
HSNMP_ENTITY hSrcEntity,hDestEntity;
//创建源主机和目的主机实体句柄
hSrcEntity = SnmpStrToEntity(m_hSession,GetLocalIP().c_str());
hDestEntity = SnmpStrToEntity(m_hSession,m_IP.c_str());
//创建变量绑定列表
if((hVbl = SnmpCreateVbl(m_hSession,NULL,NULL)) == SNMPAPI_FAILURE)
return false;
//点分十进制串转换成二进制格式
for(strvec::const_iterator it=strOIDArray.begin();it!=strOIDArray.end();it++)
{SnmpStrToOid((*it).c_str(),&sOid);
SnmpSetVb(hVbl,0,&sOid,NULL);
}
//将数据转换成特定PDU格式
if((hPdu = SnmpCreatePdu(m_hSession,sPDUType,0,NULL,NULL,hVbl)) == SNMPAPI_FAILURE)
return false;
//发送PDU
if(SnmpSendMsg(m_hSession,hSrcEntity,hDestEntity,m_hContext,hPdu) == SNMPAPI_FAILURE)
return false;
//释放句柄
SnmpFreeEntity(hSrcEntity);
SnmpFreeEntity(hDestEntity);
SnmpFreePdu(hPdu);
SnmpFreePdu(hVbl);
return true;
}
//SNMP消息接收函数
bool CManager::Receive(HSNMP_VBL& hVbl)
{WaitForSingleObject(m_hEvent,INFINITE);
ResetEvent(m_hEvent);
HSNMP_ENTITY hSrcEntity;
HSNMP_ENTITY hDestEntity;
HSNMP_CONTEXT hContext;
HSNMP_PDU hPdu;
//接收到消息
if(SnmpRecvMsg(m_hSession,&hSrcEntity,&hDestEntity,&hContext,&hPdu) == SNMPAPI_FAILURE)
return false;
smiINT PDU_type;
smiINT error_status;
smiINT error_index;
//提取PDU中的数据
if(SnmpGetPduData(hPdu,&PDU_type,NULL,&error_status,&error_index,&hVbl) == SNMPAPI_FAILURE)
return false;
return true;
}
//SNMP数值转换函数
string CManager::ValueToString(smiVALUE sValue)
{char cBuffer[1500];
memset(cBuffer,0,1500);
switch(sValue.syntax)
{case SNMP_SYNTAX_NSAPADDR:
case SNMP_SYNTAX_IPADDR:
sprintf(cBuffer,"%d.%d.%d.%d",sValue.value.string.ptr[0],sValue.value.string.ptr[1],sValue.value.string.ptr[2],sValue.value.string.ptr[3]);
break;
case SNMP_SYNTAX_OPAQUE:
case SNMP_SYNTAX_OCTETS:
if(sValue.value.string.len==0)
sprintf(cBuffer,"OCTETS NULL");
else
{memset(sValue.value.string.ptr+sValue.value.string.len,0,1);
sprintf(cBuffer,"%s",sValue.value.string.ptr);
}
break;
case SNMP_SYNTAX_TIMETICKS:
int iHours,iMinutes,iSeconds;
long lUptime;
lUptime=sValue.value.uNumber/100;
iHours=(int)(lUptime/3600);
iMinutes=(int)((lUptime%3600)/60);
iSeconds=(int)((lUptime%60));
sprintf(cBuffer,"%d时,%d分,%d秒",iHours,iMinutes,iSeconds);
break;
case SNMP_SYNTAX_INT:
sprintf(cBuffer,"%d",sValue.value.sNumber);
break;
case SNMP_SYNTAX_UINT32:
case SNMP_SYNTAX_CNTR32:
case SNMP_SYNTAX_GAUGE32:
sprintf(cBuffer,"%U",sValue.value.uNumber);
break;
default:
sprintf(cBuffer,"NULL");
break;
}
return string(cBuffer);
}
//获得路由器信息函数
bool CManager::GetAValue(const string& strOID,string& strResult)
{HSNMP_VBL hVbl;
smiOID sOIDRecv;
smiVALUE sValue;
int iCount;
strvec strOIDArray;
strOIDArray.push_back(strOID+".0");
//发送请求列表string没有成功
if(!Send(strOIDArray,SNMP_PDU_GET))
return false;
//没有接收到应答
if(!Receive(hVbl))
return false;
//计算返回Vbl的行数
iCount = SnmpCountVbl(hVbl);
if(iCount!=1)
{strResult="SnmpCounVbl error!";
return false;
}
//取返回结果
if(SnmpGetVb(hVbl,1,&sOIDRecv,&sValue) == SNMPAPI_FAILURE)
{strResult="SnmpGetVb error!";
return false;
}
strResult=ValueToString(sValue);
SnmpFreeVbl(hVbl);
return true;
}
//获得路由表信息函数
bool CManager::GetTable(strvec strOIDArray, strvec_vec& strResultTable)
{
long lIfEnd;
HSNMP_VBL hVbl;
smiOID sOIDSend;
smiOID sOIDRecv;
smiVALUE sValue;
int iCount,iOIDLen;
char cBuffer[100];
if (strOIDArray.empty())
return false;
//计算OID标识符的长度
iOIDLen=count((strOIDArray[0]).begin(),(strOIDArray[0]).end(),'.')+1;
while(true)
{//发送请求列表string没有成功
if(!Send(strOIDArray))
return false;
//没有接收到应答
if(!Receive (hVbl))
return false;
//计算返回Vbl的行数
iCount = SnmpCountVbl(hVbl);
for(int i=0;i {//取返回结果
if(SnmpGetVb(hVbl,i+1,&sOIDRecv,&sValue)==SNMPAPI_FAILURE)
{ErrorMessage("获取结果失败!");
return false;
}
memset(cBuffer,0,100);
SnmpStrToOid(strOIDArray[i].c_str(),&sOIDSend);
SnmpOidToStr(&sOIDRecv,100,cBuffer);
strOIDArray[i]=string(cBuffer);
//判断格式是否一致,决定是否继续循环
SnmpOidCompare(&sOIDSend,&sOIDRecv,iOIDLen,&lIfEnd);
if(lIfEnd !=0)
break;
strResultTable[i].push_back(ValueToString(sValue));
}
if(lIfEnd !=0)
break;
}
SnmpFreeVbl(hVbl);
return true;
}
//获得本机地址函数
string CManager::GetLocalIP()
{char cHost[512];
PHOSTENT pHostIP;
string HostIP;
if (gethostname(cHost, sizeof(cHost))==0)
{pHostIP = gethostbyname(cHost);
if(pHostIP !=NULL)
HostIP = inet_ntoa(*(struct in_addr *)(pHostIP->h_addr_list[0]));
}
return HostIP;
}
//错误信息函数
void CManager::ErrorMessage(string strMessage)
{cout< }
//事件处理函数
void CManager::SetEvent()
{::SetEvent(m_hEvent);
}
//事件回调函数
SNMPAPI_STATUS CALLBACK CManager::Callback(HSNMP_SESSION hSession,
HWND hWnd,UINT wMsg,WPARAM wParam,LPARAM lParam,LPVOID lpClientData)
{((CManager*)lpClientData)->SetEvent();
return 1;
}
// Main.CPP: 主函数的实现
//#include "Manager.h"
void main(int argc,char *argv[])
{//检查输入命令格式
if(argc!=3)
{cout<<"Please input command:SnmpManager ip_address community"<<endl;
return;
}
//初始化CManger对象
CManager cManger(argv[1],argv[2]);
bool Status=cManger.InitSnmp();

//输出路由器的基本信息
cout<<"----------------------GetValue Text------------------------"<<endl;
string Result;
if((Status=cManger.GetAValue("1.3.6.1.2.1.1.1",Result))==false)
    cout<<"GetAnValue error!"<<endl;
else
    cout<<Result<<endl;

//输出路由器的路由表信息
cout<<"----------------------GetTable Test------------------------"<<endl;
strvec RouteOidArray;
RouteOidArray.push_back ("1.3.6.1.2.1.4.21.1.1");
RouteOidArray.push_back ("1.3.6.1.2.1.4.21.1.2");
RouteOidArray.push_back ("1.3.6.1.2.1.4.21.1.7");
RouteOidArray.push_back ("1.3.6.1.2.1.4.21.1.8");
RouteOidArray.push_back ("1.3.6.1.2.1.4.21.1.11");
strvec_vec IpResultTable(RouteOidArray.size());
if (Status=cManger.GetTable(RouteOidArray,IpResultTable)==false)
    cout<<"GetTable error"<<endl;
else
{for(strvec_vec::iterator it1=IpResultTable.begin();it1!=IpResultTable.end();it1++)
    {strvec AGroup=*it1;
        for(strvec::iterator it2=AGroup.begin();it2!=AGroup.end();it2++)
        {cout<<"*it2"<<" ";}
        cout<<endl;

}
}
}

  • 写回答

5条回答 默认 最新

  • 南屏山敲钟人 2016-01-02 04:56
    关注

    你提的问题太大了,建议自己看,不懂的地方函数名拉出来google

    评论

报告相同问题?

悬赏问题

  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?
  • ¥15 乘性高斯噪声在深度学习网络中的应用
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 C++ 头文件/宏冲突问题解决