C语言实现使用 WinSNMP API 编写 CManager 类,具体要求如下: . CManager 应实现 GetAValue 接口:该接口封装 SNMP 的 GetRequest 方法,发送一个 OID ,获取结果后返回这个 OID 对应的值。 · CManager 应实现 GetTable 接口:该接口封装 SNMP 的 GetNextRequest 方法,发送一组 OID ,获取结果后返回这个组所有 OID 对应的值。 ·编写测试程序,对上述两个功能分别进行测试。
时间: 2024-03-18 19:42:26 浏览: 185
好的,我理解了你的要求。实现这个功能需要用到 WinSNMP API 来进行 SNMP 操作,以下是一个简单的 CManager 类实现代码:
```c
#include <windows.h>
#include <snmp.h>
#pragma comment(lib, "snmpapi.lib")
class CManager
{
public:
CManager();
~CManager();
bool Initialize();
bool Uninitialize();
bool GetAValue(const char* szOID, char* szValue, DWORD dwValueSize);
bool GetTable(const char* szOID, char* szTable, DWORD dwTableSize, DWORD& dwTableRows);
private:
HSNMP_SESSION m_hSession;
};
CManager::CManager()
: m_hSession(NULL)
{
}
CManager::~CManager()
{
Uninitialize();
}
bool CManager::Initialize()
{
m_hSession = SnmpOpen(NULL, NULL, NULL, 0, SNMP_VERSION_2, SNMP_DEFAULT_RETRIES, SNMP_DEFAULT_TIMEOUT);
if (m_hSession == NULL)
{
return false;
}
return true;
}
bool CManager::Uninitialize()
{
if (m_hSession != NULL)
{
SnmpClose(m_hSession);
m_hSession = NULL;
}
return true;
}
bool CManager::GetAValue(const char* szOID, char* szValue, DWORD dwValueSize)
{
if (m_hSession == NULL)
{
return false;
}
SNMPAPI_STATUS nStatus;
AsnObjectIdentifier snmpOID;
snmpOID.idLength = MAX_OID_LEN;
nStatus = SnmpMgrStrToOid(szOID, &snmpOID);
if (nStatus != SNMPAPI_SUCCESS)
{
return false;
}
SNMP_VAR_BIND varBind;
varBind.name = snmpOID;
varBind.value.asnType = ASN_NULL;
nStatus = SnmpMgrGet(m_hSession, &varBind);
if (nStatus != SNMPAPI_SUCCESS)
{
return false;
}
if (varBind.value.asnType == ASN_NULL)
{
szValue[0] = '\0';
}
else
{
DWORD dwLength = dwValueSize;
SnmpUtilOidToA(&varBind.value.asnValue.object, szValue, &dwLength);
}
return true;
}
bool CManager::GetTable(const char* szOID, char* szTable, DWORD dwTableSize, DWORD& dwTableRows)
{
if (m_hSession == NULL)
{
return false;
}
SNMPAPI_STATUS nStatus;
AsnObjectIdentifier snmpOID;
snmpOID.idLength = MAX_OID_LEN;
nStatus = SnmpMgrStrToOid(szOID, &snmpOID);
if (nStatus != SNMPAPI_SUCCESS)
{
return false;
}
DWORD dwIndex = 0;
while (1)
{
SNMP_VAR_BIND varBind;
varBind.name = snmpOID;
varBind.value.asnType = ASN_NULL;
nStatus = SnmpMgrGetNext(m_hSession, &varBind);
if (nStatus != SNMPAPI_SUCCESS)
{
break;
}
if (SnmpUtilOidNCmp(&varBind.name, &snmpOID, snmpOID.idLength) != 0)
{
break;
}
char szIndex[MAX_OID_LEN];
DWORD dwLength = MAX_OID_LEN;
SnmpUtilOidToA(&varBind.name, szIndex, &dwLength);
if (szTable != NULL)
{
if (dwIndex == 0)
{
strcpy(szTable, szIndex);
}
else
{
strcat(szTable, ";");
strcat(szTable, szIndex);
}
strcat(szTable, "=");
switch (varBind.value.asnType)
{
case ASN_INTEGER:
char szValue[32];
sprintf(szValue, "%d", varBind.value.asnValue.number);
strcat(szTable, szValue);
break;
case ASN_OCTETSTRING:
strncat(szTable, (char*)varBind.value.asnValue.string.stream, varBind.value.asnValue.string.length);
break;
default:
strcat(szTable, "unknown type");
break;
}
}
dwIndex++;
}
dwTableRows = dwIndex;
return true;
}
```
这个类中包含了 Initialize() 和 Uninitialize() 方法来初始化和释放 WinSNMP 会话,GetAValue() 方法用于获取一个 OID 的值,GetTable() 方法用于获取一组 OID 的值。在 GetTable() 方法中,我们使用 SnmpMgrGetNext() 方法来获取下一个 OID 的值,这样可以遍历整个 OID 表并获取所有 OID 的值。
以下是一个简单的测试程序:
```c
int main()
{
CManager manager;
if (!manager.Initialize())
{
printf("Failed to initialize WinSNMP.\n");
return 0;
}
// Test GetAValue
char szValue[MAX_PATH];
if (manager.GetAValue("1.3.6.1.2.1.1.5.0", szValue, MAX_PATH))
{
printf("System name: %s\n", szValue);
}
else
{
printf("Failed to get system name.\n");
}
// Test GetTable
char szTable[MAX_PATH];
DWORD dwTableRows;
if (manager.GetTable("1.3.6.1.2.1.25.4.2.1.2", szTable, MAX_PATH, dwTableRows))
{
printf("Processes:\n");
printf("%s\n", szTable);
printf("Total rows: %d\n", dwTableRows);
}
else
{
printf("Failed to get processes.\n");
}
manager.Uninitialize();
return 0;
}
```
这个测试程序分别测试了 GetAValue 和 GetTable 方法,使用的 OID 分别是系统名称和进程列表。注意,OID 的格式是以“.”分隔的数字,例如 1.3.6.1.2.1.1.5.0 表示系统名称。
阅读全文