首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 簡易 SNMP 管理程式實戰:Windows SNMP 服務安裝與 WinSNMP API 開發

     編輯:VC 教學

環境準備:安裝 SNMP 服務

  1. 控制台 → 程式集 → 開啟或關閉 Windows 功能
  2. 勾選「簡單網路管理協定 (SNMP)」,需 Windows 安裝光碟/ISO
  3. 服務啟動:net start snmp 或 services.msc 設為自動
  4. 防火牆開放 UDP 161 (查詢) 、UDP 162 (Trap)

開發環境:Platform SDK WinSNMP 範例

  • 下載 Platform SDK (含 WinSNMP 樣本代碼)
  • 樣本路徑:PlatformSDK\Samples\NetMgmt\Snmp\Wsnmp
  • 核心檔案:wsnmputil.cpp, helper.cpp, Makefile

編譯步驟 (VC6.0 / VS.NET 2003 命令列)

> cd D:\Wsnmp
> nmake all
// 產生 WIN2000_DEBUG\wsnmputil.exe

WinSNMP API 核心流程

  1. SnmpStartup:初始化 WinSNMP 工作階段
  2. SnmpOpenSession:建立會話,指定目標 Agent IP/Community
  3. SnmpStrToOid:將字串 OID (如 1.3.6.1.2.1.1.1.0) 轉內部結構
  4. SnmpEncodeMsg / SnmpSendMsg:編碼並發送請求 (GET/GETNEXT/SET)
  5. SnmpRecvMsg:接收回應
  6. SnmpDecodeMsg / SnmpOidToStr / SnmpGetVb:解碼提取 VarBind 值
  7. SnmpCloseSession / SnmpCleanup:釋放資源

最簡 GET 請求範例 (精簡自 wsnmputil.cpp)

#include 
#include 

#pragma comment(lib, "wsnmp32.lib")

void SnmpGet(LPSTR agentIp, LPSTR community, LPSTR oidStr) {
    HSNMP_SESSION hSession;
    HSNMP_ENTITY hSrcEntity, hDstEntity;
    smiOID oid;
    smiVALUE value;
    SNMPAPI_STATUS status;

    // 1. 啟動
    if (SnmpStartup(&g_hWnd) != SNMPAPI_SUCCESS) return;

    // 2. 開啟會話
    hSrcEntity = SnmpStrToEntity(hSession, "local"); // 本機
    hDstEntity = SnmpStrToEntity(hSession, agentIp); // 目標 Agent
    hSession = SnmpOpenSession(hSrcEntity, hDstEntity, 0, 0); // 0=預設重試/超時

    // 3. OID 轉換
    SnmpStrToOid(oidStr, &oid);

    // 4. 建構 VarBind List
    smiVBL vbl = {0};
    vbl.list = (smiVENDORINFO*)SnmpUtilMemAlloc(sizeof(smiVENDORINFO));
    vbl.list[0].oid = oid;
    vbl.list[0].value.syntax = SNMP_SYNTAX_NULL; // GET 請求值為 NULL
    vbl.len = 1;

    // 5. 發送 GET 請求
    HSNMP_PDU hPdu = SnmpCreatePdu(hSession, SNMP_PDU_GET, 0, 0, &vbl);
    SnmpSendMsg(hSession, hDstEntity, hSrcEntity, hPdu);

    // 6. 接收回應 (同步阻塞)
    HSNMP_PDU hRespPdu;
    SnmpRecvMsg(hSession, &hSrcEntity, &hDstEntity, NULL, &hRespPdu);

    // 7. 解析回應
    smiVBL respVbl;
    SnmpGetPduData(hRespPdu, NULL, NULL, NULL, NULL, &respVbl);
    for (UINT i = 0; i < respVbl.len; ++i) {
        char oidBuf[256];
        SnmpOidToStr(&respVbl.list[i].oid, oidBuf);
        char valBuf[256];
        SnmpUtilVarBindToStr(&respVbl.list[i], valBuf, 256);
        printf("OID: %s = %s\n", oidBuf, valBuf);
    }

    // 8. 清理
    SnmpFreeEntity(hSrcEntity);
    SnmpFreeEntity(hDstEntity);
    SnmpCloseSession(hSession);
    SnmpCleanup();
}

int main() {
    SnmpGet("127.0.0.1", "public", "1.3.6.1.2.1.1.1.0"); // sysDescr
    return 0;
}

常用標準 OID (MIB-II)

OID名稱說明
1.3.6.1.2.1.1.1.0sysDescr系統描述
1.3.6.1.2.1.1.3.0sysUpTime系統啟動時間 (百秒)
1.3.6.1.2.1.1.5.0sysName主機名稱
1.3.6.1.2.1.2.2.1.2ifDescr介面描述 (表格,需 GETNEXT 遍歷)
1.3.6.1.2.1.2.2.1.10ifInOctets介面接收位元組
1.3.6.1.2.1.2.2.1.16ifOutOctets介面發送位元組
1.3.6.1.2.1.25.2.3.1.3hrStorageDescr儲存裝置描述 (需 HOST-RESOURCES-MIB)

進階:Trap 接收與 MIB 解析

  • Trap 接收需註冊 SnmpRegister 回呼函數,監聽 UDP 162
  • 企業級開發建議使用 Net-SNMP C 庫或 SNMP++ C++ 庫,支援 MIB 編譯、OID 名稱解析、SNMPv3 加密
  • Windows 自帶 mgmtapi.dll 提供較高層封裝 (SnmpMgrRequest),但功能較 WinSNMP 受限

避坑指南

問題解決
SnmpStartup 失敗確認 SNMP 服務已啟動、註冊表 HKLM\SYSTEM\CurrentControlSet\Services\SNMP\Parameters 正確
Timeout 無回應檢查防火牆 UDP 161、Community 字串正確 (預設 public)、Agent IP 可達
OID 解析錯誤使用 snmptranslate (Net-SNMP 工具) 驗證 OID 格式
64-bit 計數器溢位使用 ifHCInOctets (1.3.6.1.2.1.31.1.1.1.6) 等 64-bit OID
中文顯示亂碼確保 SNMP Agent 回傳 UTF-8,客戶端用 MultiByteToWideChar(CP_UTF8) 轉換

總結

Windows 內建 WinSNMP API 提供輕量級 SNMP 客戶端開發能力,無需第三方庫即可完成基本 GET/GETNEXT/SET 操作。掌握 SnmpStartup → OpenSession → StrToOid → SendMsg → RecvMsg → Decode 核心流程,即可快速構建網管工具、監控代理或資產掃描器。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved