8

プログラムが起動されているコンピューターの IP アドレスを取得して、それをクライアントに送信できるようにしたいのですが、実際の IP アドレスではなく常に 0.0.0.1 を取得します (たとえば、127.0.0.1 など)。

現在、ポートは取得できますが、IP アドレスは取得できません。

どうすれば入手できますか?

最善の解決策は、 で取得できることsockaddr_inです。これが私が現在行っていることです:

int open_connection(char* ip, int* port)
{
  int                   sock;
  struct sockaddr_in    sin;
  socklen_t             len;
  int                   i;

  i = 0;
  len = sizeof(sin);
  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    return (-1);
  bzero(&sin, sizeof(struct sockaddr_in));
  sin.sin_family = AF_INET;
  if (bind(sock, (struct sockaddr *) &sin, sizeof(sin)) != 0)
    perror("Error on bind");
  if (getsockname(sock, (struct sockaddr *)&sin, &len) != 0)
    perror("Error on getsockname");
  strcpy(ip, inet_ntoa(sin.sin_addr)); // IP = 0.0.0.0
  *port = sin.sin_port;
  return (sock);
}

編集:私は自分の考え方で間違った方向に進んでいたことを理解しています。私の質問は次のとおりです。自分の IP アドレスを取得する最善の方法は何ですか?

4

4 に答える 4

13

ソケットを 0.0.0.0 に接続bind()すると、.0.0.0 を呼び出すときにソケットが使用できる唯一の IP になりますgetsockname()。これは、ソケットがすべてのローカル インターフェイスにバインドされていることを意味します。ソケットから特定の IP を取得するには、特定の IP にバインドする必要があります。

ソケット API を使用してマシンのローカル IP を取得するのは、とにかく間違ったアプローチです。よくある間違いは、ローカル IP リストを使用gethostname()gethostbyname()たりgetaddrinfo()、ローカル IP リストを取得したりすることです。通常はそれでうまくいきますが、誤った情報を引き起こす可能性のある隠れた落とし穴がいくつかありますが、人々はその事実を無視する傾向があるか、そもそもそれについてさえ知りません (私は何年もそれについて知りませんでしたが、その後私はよりよく学んだ)。

代わりに、ローカル ネットワーク インターフェイスを列挙するには、プラットフォーム固有の API を使用する必要があります。そうすれば、より信頼できる情報が得られます。Windows にはGetAdaptersInfo()とがありGetAdaptersAddresses()ます。他のプラットフォームにはgetifaddrs(). これらは、利用可能なローカル IP を示します。次にbind()、0.0.0.0 にソケットを接続して、これらの IP のいずれかでクライアントを受け入れるかbind()、特定の IP にソケットを接続して、その IP でのみクライアントを受け入れることができます。

于 2013-04-10T01:50:39.083 に答える
1

ioctl(sock, SIOCGIFADDR, adr) を呼び出すことができます

netdevice(7) を参照

于 2017-01-09T08:17:25.343 に答える