今天為了解決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