2014-07-09 2 views
-2

검색을 시도했지만 작동중인 찾지 못했습니다. Windows에서 REAL 하드웨어 이더넷 컨트롤러와 연결된 IP 주소 얻기

는 현재 윈도우

이 지금은 기계의 실제 IP 주소를 얻을 필요 이상의 ONE 올바른 하드웨어 설치 eternet는 등 등 Hamachi를 가상 상자에 의한 제어 감지 할 수 있습니다. 내가 gethostbyname을 사용하여 그것을 시도했을 때 그것은 내 Hamachi 클라이언트의 IP 주소를 반환했습니다.

이제 실제 IP 주소를 수신하려면 100 % 견고한 방법을 찾아야합니다. 모든 링크/팁/기사/방법 정말 고맙습니다.

편집 :

지금까지이 있어요 - 레미 Lebau에 의해 sugested 방법을하지만, 내가 원하는 방식으로 작동하지 않습니다 - 항상 127.0.0.1 반환 :

int main() 
{ 
    WSADATA WSA_info; 
    if (WSAStartup(MAKEWORD(2,2),&WSA_info)!=0) 
    { 
     std::cout << "Error with WSA.\n"; 
     std::cin.get(); 
     return -1; 
    } 
    SOCKADDR_IN adress; 
    adress.sin_family = AF_INET; 
    adress.sin_port = htons(80); 
    adress.sin_addr.S_un.S_addr = inet_addr("213.241.88.40"); //its google's IP adress - to chech it I used ping google.com in cmd (maybe there is somethign wrong with this) 
    SOCKET sock; 
    if ((sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))== INVALID_SOCKET){ 
     std::cout << "Error while creating socket." << std::endl; 
     closesocket(sock); 
     WSACleanup(); 
     std::cin.get(); 
     return -1; 
    } 
    if (connect(sock,(sockaddr*)&adress,sizeof(sockaddr))== SOCKET_ERROR) { 
     std::cout << "Couldnt connect." << std::endl; 
     closesocket(sock); 
     WSACleanup(); 
     std::cin.get(); 
     return -1; 
    } 
    sockaddr_in test; 
    int len = sizeof(test); 
    getsockname(sock,(struct sockaddr *) &test, &len); 
    std::cout << inet_ntoa(test.sin_addr); 

    std::cin.get(); 
} 
+3

기계에 2 개의 올바른 하드웨어 이더넷 컨트롤러가 있다면 어떻게 될까요? – liori

+0

아마 http://stackoverflow.com/q/5213629/440558 –

+0

의 중복 그게 너무 문제가있어. 소켓을 초기화하는 데 필요한 소켓이 필요합니다. – darekg11

답변

5

PC를 연결 할 수 있습니다 동시에 여러 개의 네트워크 (인터넷, VM, VPN 등)에 각각 IP 주소를 할당 할 수 있으며 동시에 소켓을 초기화 할 수 있습니다. 그리고 점점 더 보편화 된 PC는 인터넷 모뎀을 통해 직접 연결되는 것이 아니라 홈 라우터/ICS 연결을 통해 인터넷 액세스를 얻고 있습니다.

그래서 "실제 IP 주소"는 무엇입니까? PC는 여러 개의 IP 주소를 가질 수 있으며 OS가 신경 쓰는 한 모두 "실제"입니다.

사용 가능한 로컬 IP 주소를 열거하려면 GetAdaptersInfo() 또는 GetAdaptersAddresses()을 사용할 수 있습니다. 로컬 IP 주소를 찾으려면 gethostbyname()을 사용하지 마십시오. 이는 의미가 아니며 잘못된 정보를보고 할 수 있습니다!

실제로 물어보고 싶은 질문은 - 인터넷에 액세스하는 데 사용되는 이더넷 컨트롤러의 IP를 어떻게 찾습니까? 맞습니까?

그런 이유로 인터넷에서 실행중인 외부 서버에 대한 연결 해제 소켓은 connect()이어야하며, 성공한 경우 getsockname()을 사용하여 OS가 소켓을 바인딩 한 로컬 IP 주소를 찾을 수 있습니다 :

SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 

sockaddr_in remoteaddr = {0}; 
remoteaddr.sin_family = AF_INET; 
remoteaddr.sin_addr.s_addr = inet_addr("remote ip address"); 
remoteaddr.sin_port = htons(80); 

if (connect(sock, (sock_addr*)&remoteaddr, sizeof(remoteaddr)) == 0) 
{ 
    sockaddr_in localaddr = {0}; 
    int len = sizeof(localaddr); 

    getsockname(sock, (sock_addr*)&localaddr, &len); 
    // use localaddr as needed... 
} 

closesocket(sock); 

하지만 로컬 PC의 IP 주소 만 알려줍니다. 라우터/ICS 뒤에 있다면 인터넷이 PC에 패킷을 보내는 데 사용하는 것과 동일한 IP 주소가 될 수 없습니다. 해당 IP 주소를 얻으려면 http://whatismyip.com과 같은 외부 iplookup 서비스에 연결하고 쿼리하여 다시보고하는 IP 주소를 확인하십시오.

+0

로컬 IP 주소 (라우터에 의해 할당 된 주소)가 필요하므로 예를 들어 google.com에 연결하고 그 소켓에 getsockname을 사용할 수 있습니까? 답변 해 주셔서 감사합니다. – darekg11

+0

예, 라우터 할당 로컬 IP 주소를 가져옵니다. –

+0

나는 그것을 시도했다, 나는 80 포트에 구글 IP 주소에 접속했다. 연결은 성공했지만 getsocketname은 그 소켓에 127.0.0.1을 반환한다. – darekg11

관련 문제