无法从gethostname访问Ip地址的内存 我正在开发一个后效插件,我想把它作为一个C++网络库集成起来。当raknet库试图通过调用 gethostbyname

无法从gethostname访问Ip地址的内存 我正在开发一个后效插件,我想把它作为一个C++网络库集成起来。当raknet库试图通过调用 gethostbyname,c++,winapi,network-programming,gethostbyname,C++,Winapi,Network Programming,Gethostbyname,然后,它在读取位置0xFFFFFFFFFFFFFFFF时抛出错误访问冲突 int idx=0; char ac[ 80 ]; int err = gethostname( ac, sizeof( ac ) ); (void) err; RakAssert(err != -1); struct hostent *phe = gethostbyname( ac ); if ( phe == 0 ) { RakAssert(phe!=0); return ; } for ( idx = 0; id

然后,它在读取位置0xFFFFFFFFFFFFFFFF时抛出错误访问冲突

int idx=0;
char ac[ 80 ];
int err = gethostname( ac, sizeof( ac ) );
(void) err;
RakAssert(err != -1);

struct hostent *phe = gethostbyname( ac );

if ( phe == 0 )
{
RakAssert(phe!=0);
return ;
}
for ( idx = 0; idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS; ++idx )
{
if (phe->h_addr_list[ idx ] == 0)
    break;

memcpy(&addresses[idx].address.addr4.sin_addr,phe->h_addr_list[ idx ], sizeof(struct in_addr));
}

while (idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS)
{
addresses[idx]=UNASSIGNED_SYSTEM_ADDRESS;
idx++;
}
intidx=0;
char-ac[80];
int err=gethostname(ac,sizeof(ac));
(无效)错误;
RakAssert(err!=-1);
结构hostent*phe=gethostbyname(ac);
如果(phe==0)
{
RakAssert(phe!=0);
返回;
}
对于(idx=0;idx<内部ID的最大数量;++idx)
{
如果(phe->h_地址列表[idx]==0)
打破
memcpy(&addresses[idx].address.addr4.sin_addr,phe->h_addr_list[idx],sizeof(struct in_addr));
}
而(idx<内部ID的最大数量)
{
地址[idx]=未分配的系统地址;
idx++;
}
这是我看到的一些照片

我读过这篇文章,看起来图书馆并没有错误地实现它。

当我将鼠标悬停在h_addr_列表和h_别名上时,我会得到

有人有什么想法吗?为什么会失败?我很确定这是一个常见的函数


另一件事,winsock和winsock2的gethostbyname函数实现之间有什么区别吗?

这就是我提出的解决方案。 Aparently gethostname不是线程安全的。After effects是多线程的

我换了这个

int idx=0;
char ac[ 80 ];
int err = gethostname( ac, sizeof( ac ) );
(void) err;
RakAssert(err != -1);

struct hostent *phe = gethostbyname( ac );

if ( phe == 0 )
{
    RakAssert(phe!=0);
    return ;
}
for ( idx = 0; idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS; ++idx )
{
    if (phe->h_addr_list[ idx ] == 0)
        break;

    memcpy(&addresses[idx].address.addr4.sin_addr,phe->h_addr_list[ idx ],sizeof(struct in_addr));
}

while (idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS)
{
    addresses[idx]=UNASSIGNED_SYSTEM_ADDRESS;
    idx++;
}
intidx=0;
char-ac[80];
int err=gethostname(ac,sizeof(ac));
(无效)错误;
RakAssert(err!=-1);
结构hostent*phe=gethostbyname(ac);
如果(phe==0)
{
RakAssert(phe!=0);
返回;
}
对于(idx=0;idx<内部ID的最大数量;++idx)
{
如果(phe->h_地址列表[idx]==0)
打破
memcpy(&addresses[idx].address.addr4.sin_addr,phe->h_addr_list[idx],sizeof(struct in_addr));
}
而(idx<内部ID的最大数量)
{
地址[idx]=未分配的系统地址;
idx++;
}
用这个

int idx=0;
struct addrinfo* feed_server = NULL;
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
getaddrinfo("localhost", NULL, &hints, &feed_server);
struct addrinfo *res;
for(res = feed_server; res != NULL; res = res->ai_next) {
    struct sockaddr_in* saddr = (struct sockaddr_in*)res->ai_addr;
    //char* ipv4Str = inet_ntoa(saddr->sin_addr);
    memcpy(&addresses[idx].address.addr4.sin_addr, &saddr->sin_addr, sizeof(struct in_addr));
    idx++;
} 
while (idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS) {
    addresses[idx]=UNASSIGNED_SYSTEM_ADDRESS;
    idx++;
}
intidx=0;
struct addrinfo*feed_server=NULL;
结构addrinfo提示;
memset(&hints,0,sizeof(struct addrinfo));
hits.ai_family=AF_INET;
getaddrinfo(“localhost”、NULL、提示和提要服务器);
结构addrinfo*res;
对于(res=feed\u server;res!=NULL;res=res->ai\u next){
结构sockaddr_in*saddr=(结构sockaddr_in*)res->ai_addr;
//char*ipv4Str=inet\u ntoa(saddr->sin\u addr);
memcpy(&addresses[idx].address.addr4.sin_addr,&saddr->sin_addr,sizeof(struct in_addr));
idx++;
} 
而(idx<内部ID的最大数量){
地址[idx]=未分配的系统地址;
idx++;
}
这就是为什么我走这条路。有人反对吗


我很惊讶Windows实现不是线程安全的,而且每个主机都使用线程本地存储。但无论如何

只需使用解析主机名。它是线程安全的,可以替代gethostname


但您的最终目标是枚举框上的本地IP地址。在这种情况下,只需在UNIX上使用,并在Windows上结合使用,即可枚举本地IP地址。您也可以将与Windows上的虚拟套接字一起使用。

请不要发布代码的图片。在键入代码时发布代码。在任何情况下,它都不太可能在gethostbyname上崩溃,否则您将无法调试它,直到将“phe”分配给有效的对象。gethostbyname调用下面的for循环看起来可疑,但我看不出for循环条件表达式是什么,因为它被调试窗口遮住了,break语句下面的相关部分被切断了。请将整个正文发布到GetMyIP函数调用中。很抱歉,我忘了包含代码。。更新的问题Winsock的
gethostbyname()
实现是线程安全的,并且使用TLS。甚至有人这样说:“gethostbyname函数返回的hostent结构的内存是由Winsock DLL从线程本地存储内部分配的。”但是,您是对的,
gethostbyname/getaddrinfo()
不应用于获取调用PC的本地IP地址,
getifaddrs()应改用
GetAdapterAddresses/GetAdapterInfo()
。该错误报告适用于FreeBSD,而不是Windows。
gethostbyname()
的Windows实现是线程安全的。你是对的,我错了。。它可能不再被使用,应该被弃用。