Невозможно получить доступ к памяти IP-адреса из gethostname

Я разрабатываю плагин для постэффектов и пытаюсь интегрировать raknet, который является сетевой библиотекой c ++. Когда библиотека raknet пытается получить адрес ipv4, вызвав

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; 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++;
}

Вот несколько фотографий того, что я вижу.

http://jacobsgriffith.com/stackoverflow/noaccesserror.png

Я прочитал это, и не похоже, что библиотека реализовала это неправильно.
Документация Microsoft по gethostbyname

Когда я наведите курсор на h_addr_list и h_aliases, я получаю.

http://jacobsgriffith.com/stackoverflow/noaccess.jpg

У кого-нибудь есть идеи? Почему это терпит неудачу, я почти уверен, что это обычная функция.

Другое дело, есть ли разница между реализациями функции gethostbyname от winsock и winsock2?

0

Решение

Я удивлен, что реализация Windows не является поточно-ориентированной и использует локальное хранилище для каждого хоста. Но в любом случае …

Просто используйте getaddrinfo разрешить имена хостов. Это потокобезопасный и предназначен для замены gethostname.

Но ваша конечная цель — перечислить локальные IP-адреса на коробке. В этом случае просто используйте getifaddrs на UNIX и сочетание GetAdaptersInfo и GetAdatperAddresses в Windows перечислить локальные IP-адреса. Вы также можете использовать SIO_ADDRESS_LIST_QUERY ioctl с фиктивной розеткой на винде.

1

Другие решения

Это решение, которое я придумал.
Очевидно, gethostname не является потокобезопасным. Последствия многопоточные.

Я заменил это

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++;
}

с этим

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++;
}

И именно поэтому я пошел по этому пути. Кто-нибудь возражал?

gethostname не безопасно

0

По вопросам рекламы [email protected]