2013-03-07 4 views
0

저는 After Effects 플러그인을 개발 중이며 C++ 네트워크 라이브러리 인 raknet을 통합하려고합니다. raknet 라이브러리gethostname에서 IP 주소의 메모리에 액세스 할 수 없습니다

gethostbyname 

를 호출하여 IPv4 주소를 얻으려고 노력하면 그 다음 여기에 내가 무엇을보고 몇 가지 사진입니다 오류 액세스 위반 읽기 위치

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

내지 0xFFFFFFFFFFFFFFFF

가 발생합니다.

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

나는 이것을 읽은와 라이브러리가 잘못 구현처럼은 보이지 않는다. Microsoft Documentation On gethostbyname

내가 h_addr_list 및 h_aliases에 마우스를 가져 가면 얻을 수 있습니다.

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

누구나 어떤 아이디어가? 이것이 실패하는 이유는 이것이 공통 기능이라고 확신합니다.

또 다른 것은 winsock과 winsock2의 gethostbyname 함수 구현간에 차이가 있습니까?

+0

코드 사진을 게시하지 마십시오. 입력 한대로 코드를 게시하십시오. 어쨌든 gethostbyname에서 충돌이 발생할 가능성이 크지 않습니다. 그렇지 않으면 무언가에 "phe"가 할당 된 지점까지 디버깅 할 수 없었을 것입니다. 그 for-loop 아래의 gethostbyname 호출은 의심스러워 보이지만 for-loop 조건식은 디버그 창에 의해 가려져 break 문 아래의 관련 부분이 잘 리기 때문에 볼 수 없습니다. 전체 몸체를 GetMyIP 함수 호출에 게시하십시오. – selbie

+0

죄송합니다. 코드를 잊어 버렸습니다 .. 업데이트 된 질문 – jacobsgriffith

답변

0

이것은 내가 생각해 낸 해결책입니다. 실제로 gethostname은 스레드로부터 안전하지 않습니다. After Effects는 멀티 스레드입니다.

나는이

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

으로이

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

대체 내가 그 길을 갔다 이유입니다. 누구?

gethostname not thread safe

+0

버그 보고서는 Windows가 아니라 FreeBSD 용입니다. Windows에서 구현 된'gethostbyname()'은 스레드로부터 안전합니다. –

+0

네 말이 맞아. 내가 틀렸어.더 이상 사용하지 않아야하며 사용되지 않는 것이 좋습니다. – jacobsgriffith

1

나는 윈도우 구현이 각각 상응하는 hostent 안전하고 사용하여 스레드 로컬 저장소 스레드되지 않은 놀랍군요. 하지만 어쨌든 ...

getaddrinfo을 사용하면 호스트 이름을 확인할 수 있습니다. 이것은 쓰레드에 안전하며 gethostname의 대체품입니다.

하지만 궁극적 인 목표는 상자의 로컬 IP 주소를 열거하는 것입니다. 이 경우 UNIX에서는 getifaddrs을, Windows에서는 GetAdaptersInfo and GetAdatperAddresses을 조합하여 로컬 IP 주소를 열거하십시오. Windows에서 SIO_ADDRESS_LIST_QUERY ioctl을 더미 소켓과 함께 사용할 수도 있습니다.

+0

WinSock의'gethostbyname()'구현은 스레드로부터 안전하며 TLS를 사용합니다. [문서] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms738524.aspx)도 이렇게 말합니다. "gethostbyname 함수가 반환 한 hostent 구조체의 메모리는 내부적으로 스레드 로컬 저장소에서 Winsock DLL을. " –

+0

하지만 gethostbyname/getaddrinfo()는 호출하는 PC의 로컬 IP 주소를 가져 오는 데 사용해서는 안되며 대신 getifaddrs() 및 GetAdaptersAddresses/GetAdaptersInfo()를 사용해야합니다. –