为什么值发生意外变化?inet_ntoa



我正在尝试创建一个函数,该函数收集机器上存在的所有IP,并能够检测何时存在IP in参数。

问题是在另一个IN_ADDR上执行inet_ntoa之后,包含我的IP的变量的值正在更改。

我尝试使用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 don");
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 GetIpAddrTablen");
//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 %sn", IPName);
printf("tIP Address[%d]:     t%sn", i, inet_ntoa(IPAddr));
printf("2- The value of IPName is %sn", IPName);
//if (strcmp(IPName, inet_ntoa(IPAddr)) == 0) {
//    printf("IP adress[%s] is found in AddrTablen", 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 %dn", dwRetVal);
printf("Required size should be %dn", 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, 0, 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或此处的Linux(,结果是指向静态缓冲区的指针:

返回的字符串保证只有在同一线程内进行下一次Windows套接字函数调用之前才有效。因此,应在进行另一个Windows套接字调用之前复制数据。

您所需要做的就是将缓冲区的内容复制到字符串变量中。

char IPName[18];
char* temp = inet_ntoa(WFIAddr.sin_addr); 
if (temp != NULL)
{
strcpy(IPName, temp);
}

(有关缓冲区大小的详细信息,请参阅此处(

当然,您应该处理错误情况(如果tempNULL(

最新更新