2011-11-12 45 views
2

友人はfollowing snippet of codeを使用して、LAN内のホストのローカルIPアドレスを取得しました。gethostbyname()を使用してローカルIPを取得できません

int buffersize = 512; 
char name[buffersize]; 

if(gethostname(name, buffersize) == -1){ 
    Exception excep("Failed to retrieve the name of the computer"); 
    excep.raise(); 
} 

struct hostent *hp = gethostbyname(name); 
if(hp == NULL){ 
    Exception excep("Failed to retrieve the IP address of the local host"); 
    excep.raise(); 
} 

struct in_addr **addr_list = (struct in_addr **)hp->h_addr_list; 
for(int i = 0; addr_list[i] != NULL; i++) { 
    qDebug() << QString(inet_ntoa(*addr_list[i])); 
} 

Macでは問題なく動作しているようです。彼は、その配列内の最後のIPアドレスは、知っておく必要があるものだと言いました。しかし、私は自分のLinuxノートパソコンでこれらの値を得ました...

これらは私のアダプターで使用されている値と似ていますが、同じではありません。ここではいくつかのifconfigのデータがあります:

eth0  Link encap:Ethernet HWaddr 1C:C1:DE:91:54:1A 
      UP BROADCAST MULTICAST MTU:1500 Metric:1 
lo  Link encap:Local Loopback 
      inet addr:127.0.0.1 Mask:255.0.0.0 
wlan0  Link encap:Ethernet HWaddr [bleep] 
      inet addr:192.168.1.6 Bcast:192.168.1.255 Mask:255.255.255.0 

ビットの一部がスクランブルされたことが表示されます。私たちはここで重要な転換を逃していますか?あなたが本当にのQtを使用している場合

+0

私はあなたのコードをWindows上でテストしました(VS2010; ExceptionとQStringを使用していませんでした)、IPアドレスのOK値を返しています。 –

+0

ホストが特定のデータを保存する方法に違いがあるのでしょうか?私は、ネットワークは普遍的に合意されたデータ表現方法を持っていると言われてきました。そのため、特定のものについて「ネットワークからホスト」および「ホストからネットワーク」への変換を行う必要があります。 – Pieter

+0

'inet_ntoa'は廃止されました。しかし、次に、 'addr_list'の各文字列をどのようにデコードするのですか?マンページはネットワークバイトオーダーでコード化されているので、ホストの順序に戻しますか?私は各文字に対して 'ntohs()'を試みましたが、それは期待された結果を持っていませんでした。 – Pieter

答えて

0

「正しい」ローカルホスト名と「正しく設定された」DNSシステムに依存する方法を提案します。 DNSに登録されていないローカルホスト名を使用すると、あなたのプログラムを除くすべての目的に完全に有効です。

接続されたソケットがある場合(または接続されたソケットを生成できる場合)ローカルIPアドレスを見つけるには、getsockname()を使用することをお勧めします。 (注:のローカルIPアドレスではありません)。

これを行うサンプルプログラムは、次のとおりです。明らかに、そのほとんどはgoogle.comに接続して結果を出力しています。 getsockname()への電話だけがあなたの質問に密接に関連しています。

#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 

#include <stdio.h> 
#include <errno.h> 
#include <unistd.h> 


int main(int ac, char **av) { 
    addrinfo *res; 
    if(getaddrinfo("google.com", "80", 0, &res)) { 
     fprintf(stderr, "Can't lookup google.com\n"); 
     return 1; 
    } 

    bool connected = false; 
    for(; res; res=res->ai_next) { 
     int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 
     if(fd < 0) { 
      perror("socket"); 
      continue; 
     } 

     if(connect(fd, res->ai_addr, res->ai_addrlen)) { 
      perror("connect"); 
      close(fd); 
      continue; 
     } 

     sockaddr_in me; 
     socklen_t socklen = sizeof(me); 
     if(getsockname(fd, (sockaddr*)&me, &socklen)) { 
      perror("getsockname"); 
      close(fd); 
      continue; 
     } 

     if(socklen > sizeof(me)) { 
      close(fd); 
      continue; 
     } 

     char name[64]; 
     if(getnameinfo((sockaddr*)&me, socklen, name, sizeof name, 0, 0, NI_NUMERICHOST)) { 
      fprintf(stderr, "getnameinfo failed\n"); 
      close(fd); 
      continue; 
     } 
     printf("%s ->", name); 

     if(getnameinfo(res->ai_addr, res->ai_addrlen, name, sizeof name, 0, 0, NI_NUMERICHOST)) { 
      fprintf(stderr, "getnameinfo failed\n"); 
      close(fd); 
      continue; 
     } 
     printf("%s\n", name); 
     close(fd); 
    } 
} 
+0

ありがとう - それは私のトリックです。 – Pieter

0

することは、あなたがこのコード

foreach (const QHostAddress& address, QNetworkInterface::allAddresses()) { 
     qDebug() << address.toString(); 
    } 

を使用することができますが、Qtのを使用していない場合、あなたはそれがそこに作られているか、勉強することができます。

+0

私はこれをComputer Networkingコースの課題として作っています。私たちは、低レベルのものについてより多くの洞察を得るために、ネットワーク関連の何かをするために外部ライブラリを使用することを許可しません。これは将来のプロジェクトには役立ちますが、感謝します。 – Pieter

関連する問題