Я разрабатываю плагин для постэффектов и пытаюсь интегрировать 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?
Я удивлен, что реализация Windows не является поточно-ориентированной и использует локальное хранилище для каждого хоста. Но в любом случае …
Просто используйте getaddrinfo разрешить имена хостов. Это потокобезопасный и предназначен для замены gethostname.
Но ваша конечная цель — перечислить локальные IP-адреса на коробке. В этом случае просто используйте getifaddrs на UNIX и сочетание GetAdaptersInfo и GetAdatperAddresses в Windows перечислить локальные IP-адреса. Вы также можете использовать SIO_ADDRESS_LIST_QUERY ioctl с фиктивной розеткой на винде.
Это решение, которое я придумал.
Очевидно, 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++;
}
И именно поэтому я пошел по этому пути. Кто-нибудь возражал?