如何解决为什么值会意外变化? inet_ntoa
我正在尝试创建一个函数,该函数收集机器上存在的所有 IP,并且能够检测参数中的 IP 何时存在。
问题是包含我的 IP 的变量的值在另一个 IN_ADDR 上完成 inet_ntoa 后发生了变化。
我尝试使用 std::string 没有成功。我知道 inet_ntoa 已被弃用,但我尝试了其他方法但没有成功。我也想了解我做错了什么。
void CIPUtilities::AwaitIPAddress(struct sockaddr_in WFIAddr) {
// also tried with AwaitIPAddress(char * IPName)
char* IPName = inet_ntoa(WFIAddr.sin_addr);
printf("\n Waiting for the IP: %s to be ready.\n",IPName);
int i;
bool ctn = TRUE;
/* Variables used by GetIpAddrTable */
PMIB_IPADDRTABLE pIPAddrTable;
DWORD dwSize = 0;
DWORD dwRetVal = 0;
IN_ADDR IPAddr;
ULONG outBufLen = 0;
ULONG Iterations = 0;
/* Variables used to return error message */
LPVOID lpMsgBuf;
// Allocate a 15 KB buffer to start with.
outBufLen = WORKING_BUFFER_SIZE;
do {
do {
//printf("inside do\n");
Sleep(300); //to be removed ? Only there to avaoid to loop too much.
pIPAddrTable = (MIB_IPADDRTABLE*)MALLOC(outBufLen);
if (pIPAddrTable == NULL) {
printf("Memory allocation Failed for GetIpAddrTable\n");
//exit(1); // no need to exit we need debug
}
dwRetVal = GetIpAddrTable(pIPAddrTable,&outBufLen,0);
if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
FREE(pIPAddrTable);
pIPAddrTable = NULL;
}
else {
break;
}
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < MAX_TRIES));
if (dwRetVal == NO_ERROR) {
// If successful,search the IP from the data we retrived
for (i = 0; i < (int)pIPAddrTable->dwNumEntries; i++) {
IPAddr.S_un.S_addr = (u_long)pIPAddrTable->table[i].dwAddr;
printf("1- The value of IPName is %s\n",IPName);
printf("\tIP Address[%d]: \t%s\n",i,inet_ntoa(IPAddr));
printf("2- The value of IPName is %s\n",IPName);
//if (strcmp(IPName,inet_ntoa(IPAddr)) == 0) {
// printf("IP adress[%s] is found in AddrTable\n",inet_ntoa(IPAddr));
// ctn = FALSE; // We exit the loop because the adress is created.
// break; // no need to parse more addresses.
//}
}
}
else
{
printf("GetIpAddrTable Failed with error %d\n",dwRetVal);
printf("required size should be %d\n",dwSize);
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYstem | FORMAT_MESSAGE_IGnorE_INSERTS,NULL,dwRetVal,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),// Default language
(LPTSTR)&lpMsgBuf,NULL)) {
printf("\tError: %s",(char*)lpMsgBuf);
LocalFree(lpMsgBuf);
}
//exit(1); // no need to exit we need debug
}
if (pIPAddrTable) {
FREE(pIPAddrTable);
pIPAddrTable = NULL;
}
} while (ctn);}
基本上输出将是:
Waiting for the IP: 10.0.4.3 to be ready.
1- The value of IPName is 10.0.4.3
IP Address[0]: 160.223.17.135
2- The value of IPName is 160.223.17.135
1- The value of IPName is 160.223.17.135
IP Address[1]: 169.254.165.50
2- The value of IPName is 169.254.165.50
1- The value of IPName is 169.254.165.50
IP Address[2]: 10.0.4.3
2- The value of IPName is 10.0.4.3
1- The value of IPName is 10.0.4.3
IP Address[3]: 10.0.12.44
2- The value of IPName is 10.0.12.44
1- The value of IPName is 10.0.12.44
IP Address[4]: 192.168.0.17
2- The value of IPName is 192.168.0.17
1- The value of IPName is 192.168.0.17
IP Address[5]: 127.0.0.1
2- The value of IPName is 127.0.0.1
1- The value of IPName is 127.0.0.1
解决方法
简而言之:发生这种情况是因为您直接使用返回的指针而不是复制字符串。
char* IPName = inet_ntoa(WFIAddr.sin_addr);
如 inet_ntoa 文档中所述(Windows 参见 here 或 Linux 参见 here)结果是一个指向 static 缓冲区的指针:
保证返回的字符串仅在同一线程内进行下一次 Windows Sockets 函数调用之前有效。因此,应在进行另一个 Windows Sockets 调用之前复制数据。
您需要做的就是将缓冲区的内容复制到字符串变量中。
char IPName[18];
char* temp = inet_ntoa(WFIAddr.sin_addr);
if (temp != NULL)
{
strcpy(IPName,temp);
}
(有关缓冲区大小的详细信息,请参阅 here)
当然,您应该处理错误情况(如果 temp is NULL)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。