【发布时间】:2014-08-21 05:58:52
【问题描述】:
新更新: 因此,在 Windows Server 2012 上,如果我从 Windows\System32 手动调用 snmp.exe 以“以管理员身份运行”,问题就会消失。我无法强制 SNMP 服务在 Windows Server 2012 上以管理员身份启动。
这是我的场景:
- 我们的 SNMP 扩展代理创建一个 windows 套接字来连接我们的一个 特定端口号上的代理以获取一些配置 我们传播到 MIB 浏览器的信息。
- 当我们重新安装我们的应用程序然后安装 Windows Server 2012 上的 SNMP,一切正常。
- 重新启动后,对扩展代理的任何 SNMP 请求都会超时 由 MIB 浏览器提供。我从扩展代理调试并发现 在 connect() 调用中我们得到了一个“WSAEACCES (10013) Permission denied error”。请看下面代码中的注释。
- 同样的事情在 Windows Server 2008 上运行良好。
下面是sn-p的代码:
struct sockaddr_in dest;
int sockfd;
char buffer;
int bytes_read;
char portNumberStr[10];
int iResult;
struct addrinfo *result = NULL, *ptr = NULL, hints;
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(2, 2);
iResult = WSAStartup(wVersionRequested, &wsaData);
if (iResult != 0)
{
int WSAError = WSAGetLastError();
return SOAP_NO_SOCKET_ERROR;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
sprintf(portNumberStr, "%d", port_number);
iResult = getaddrinfo("127.0.0.1", portNumberStr, &hints, &result);
if (iResult != 0)
{
int WSAError = WSAGetLastError();
WSACleanup();
return SOAP_NO_SOCKET_ERROR;
}
// Loop through the results addrinfo structure
bool connectionSuccess = false;
for(ptr = result; ptr != NULL; ptr = result->ai_next)
{
// Create a socket
sockfd = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (INVALID_SOCKET == sockfd)
{
int WSAError = WSAGetLastError();
continue;
}
iResult = connect(sockfd, ptr->ai_addr, (int)ptr->ai_addrlen); // This is the call where I get a WSAEACCES (10013) error.
if (iResult == SOCKET_ERROR)
{
int WSAError = WSAGetLastError();
closesocket(sockfd);
continue;
}
connectionSuccess = true;
break;
}
// Clean up
freeaddrinfo(result);
if(false == connectionSuccess)
{
return SOAP_ERROR;
}
// Form the Request
*localRequest = "Request goes in here"
// Send the message to the agent through a TCP socket.
send(sockfd,localRequest->c_str(),(int)localRequest->length(), 0);
// Clear out the request string so we can use it to hold a response.
*localRequest = "";
// Keep getting bytes from server until finished.
do
{
bytes_read = recv(sockfd, &buffer, sizeof(buffer), 0);
if ( bytes_read > 0 )
{
localRequest->append(1,buffer);
}
}
while ( bytes_read > 0 );
closesocket(sockfd);
WSACleanup();
与独立应用程序相同的代码能够与我们的代理通信并获取所需的数据。
如果您需要更多信息,请告诉我还有什么可以尝试的。
感谢和问候 阿迪亚
【问题讨论】:
-
用代码 sn-p 更新了问题。
-
您的
connect()循环需要改为for(ptr = result; ptr != NULL; ptr = ptr->ai_next)。您应该考虑更改您的recv()循环以一次读取超过1 个字节。recv()会告诉你它实际读取了多少字节。 -
是的,port_number 作为参数进入此函数。并且循环出现复制粘贴错误。
-
找到这篇适用于 Windows 8/2012 (support.microsoft.com/kb/2771908) 的知识库文章,其中描述了完全相同的问题。为了避免这种情况,我们可以编写我们的 power shell 脚本来启用到特定端口的入站和出站 TCP 连接。请在此处找到链接 (p0w3rsh3ll.wordpress.com/2014/01/02/…)