天天看點

net-snmp開發中出現“Error opening specified endpoint"" ”的解決方案#if defined(linux) && defined(IP_PKTINFO)#elif !defined(WIN32) && defined(IP_RECVDSTADDR)#endif

       今天為了解決net-snmp開發中出現的“Error opening specified endpoint"" “,不知費了我多少腦細胞,還好問題解決,終得完美。倍感欣慰之餘,發表CSDN的第一篇博文。

        “Error opening specified endpoint"" “出現在SNMP運作中,表示的是無法打開UDP端口(通常是UDP:161)。目前大緻有三種原因引起這個錯誤。原因和解決方法如下:

         1 UDP端口被占用

          當UDP端口161被本機的SNMP或其他程式占用後,肯定會出現錯誤“Error opening specified endpoint"" “。

          解決方案:

        (1)在開始--運作   裡面輸入cmd點回車,會出現運作視窗。

        (2)在提示符後輸入netstat -ano回車,查詢是否udp 161被占用。如果有,則找到udp 161端口對應的pid,繼續下一步。如果沒有,則排除這種情況。

        (3)打開任務管理器,在‘  檢視--選擇列--在PID(程序标示符)’前面打鈎。下面的程序或服務前面都有了PID号碼,找到PID所對應的程序或服務,點選結束。

            這時程式就可以運作了。

         2  未使用管理者身份運作

         如果未使用管理者身份運作SNMP的話,有可能會出現錯誤“Error opening specified endpoint"" “。

          解決方案:

          如果在Window系統中,使用Administrator身份運作程式;如果在Linux中,輸入”sudo snmpd“。

        3  net snmp版本不支援較低版本的Windows系統

        某些net snmp版本在XP或Server2003中開發運作時,會出現socket連接配接錯誤,導緻出現“Error opening specified endpoint"" “。(我遇見的就是這種情況,源代碼在win7上開發的,win7使用沒問題,但在XP或Server2003上就會出現錯誤。一步步跟程式,才發現socket無法連接配接上,上網google了一下,找到國外某大牛提供的解決方法,試了一下,果然能行,嘿嘿,松了口氣。) 解決方案網址:   http://sourceforge.net/p/net-snmp/bugs/2438/

 解決方案:       

缺陷問題存在于:

/net-snmp/snmplib/transports/snmpUDPIPv4BaseDomain.c

功能函數:

netsnmp_udpipv4base_transport

下面是解決問題的一種可行性方法。顯示新舊代碼::

#if defined(linux) && defined(IP_PKTINFO)

{ 
        int sockopt = 1;
        if (setsockopt(t->sock, SOL_IP, IP_PKTINFO, &sockopt, sizeof sockopt) == -1) {
            DEBUGMSGTL(("netsnmp_udpbase", "couldn't set IP_PKTINFO: %s\n",
                strerror(errno)));
            netsnmp_transport_free(t);
            return NULL;
        }
        DEBUGMSGTL(("netsnmp_udpbase", "set IP_PKTINFO\n"));
    }
      

//  更改部分開始

//  舊代碼

// #elif defined(IP_RECVDSTADDR)

//  新代碼

#elif !defined(WIN32) && defined(IP_RECVDSTADDR)

//  更改結束

        {

int sockopt = 1;

if (setsockopt(t->sock, IPPROTO_IP, IP_RECVDSTADDR, &sockopt, sizeof sockopt) == -1) {

DEBUGMSGTL(("netsnmp_udp", "couldn't set IP_RECVDSTADDR: %s\n",

strerror(errno)));

netsnmp_transport_free(t);

return NULL;

}

DEBUGMSGTL(("netsnmp_udp", "set IP_RECVDSTADDR\n"));

}

#endif

 還有一種修改方法:http://sourceforge.net/p/net-snmp/patches/1249/ 中提出将IP_RECVDSTADDR更改為IP_PKTINFO,似乎能适應更多的作業系統。

即将

#elif defined(IP_RECVDSTADDR)

        {

            int sockopt = 1;

            if (setsockopt(t->sock, IPPROTO_IP, IP_RECVDSTADDR, &sockopt, sizeof sockopt) == -1) {

                DEBUGMSGTL(("netsnmp_udp", "couldn't set IP_RECVDSTADDR: %s\n",

                            strerror(errno)));

                netsnmp_transport_free(t);

                return NULL;

            }

            DEBUGMSGTL(("netsnmp_udp", "set IP_RECVDSTADDR\n"));

        }

#endif

更改為

#elif defined(IP_PKTINFO)

        {

            int sockopt = 1;

            if (setsockopt(t->sock, IPPROTO_IP, IP_PKTINFO, &sockopt, sizeof sockopt) == -1) {

                DEBUGMSGTL(("netsnmp_udp", "couldn't set IP_PKTINFO: %s\n",

                            strerror(errno)));

                netsnmp_transport_free(t);

                return NULL;

            }

            DEBUGMSGTL(("netsnmp_udp", "set IP_PKTINFO\n"));

        }

#endif

繼續閱讀