ソケットプログラミングのためのINADDR_ANYの理解


84

私はいくつかのソケットをプログラムしようとしているので、サーバー側ではを使用しますhtonl(INADDR_ANY)。私が理解している限りでは、この関数はランダムなIPを生成しているように見えます(私は正しいですか?)。実際、ソケットをにバインドしたいと思いlocalhostます。しかし、これを実行すると

printf("%d",htonl(INADDR_ANY));

戻り値として0を取得します。誰かが説明を持ってくることができますか?


9
" ...私は使用しますhtonl(INADDR_ANY)。ドキュメントには、この関数がランダムIPを生成すると書かれています... "これは正しくありません。どのドキュメントがそう言っていますか?
2013年

1
@alk、実際私は誤解を招きます:私はいくつかの公式文書だと思ったpdfを読んでいました。私は今自分の投稿を編集しています
epsilones 2013年

回答:


132
  1. bind()ofINADDR_ANYは「ランダムIPを生成」しませんソケットを使用可能なすべてのインターフェースバインドします

  2. サーバーの場合、通常、「localhost」だけでなく、すべてのインターフェースにバインドする必要があります。

  3. ソケットをローカルホストのみにバインドする場合、構文は次のようmy_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1");になりますbind(my_socket, (SOCKADDR *) &my_sockaddr, ...)。次に、を呼び出します。

  4. たまたまINADDR_ANY「ゼロ」に等しい定数です。

    http://www.castaglia.org/proftpd/doc/devel-guide/src/include/inet.h.html

    # define INADDR_ANY ((unsigned long int) 0x00000000)
    ...
    # define INADDR_NONE    0xffffffff
    ...
    # define INPORT_ANY 0
    ...
    
  5. まだ慣れていない場合は、Beejのソケットプログラミングガイドを確認することをお勧めします。

    http://beej.us/guide/bgnet/

人々はまだこれを読んでいるので、追加の注意:

man(7)ip

プロセスが新しい着信パケットまたは接続を受信する場合は、bind(2)を使用してソケットをローカルインターフェイスアドレスにバインドする必要があります。

この場合、特定のローカル(アドレス、ポート)ペアにバインドできるIPソケットは1つだけです。バインド呼び出しでINADDR_ANYが指定されている場合、ソケットはすべてのローカルインターフェイスにバインドされます。

ときに(2)を聞くソケットが自動的にINADDR_ANYへのローカルアドレスを設定して、ランダムな空きポートにバインドされ、結合していないソケットに対して呼ばれます。

とき(2)接続バインドされていないソケットで呼び出され、ソケットは自動的にランダム空きポートまたはINADDR_ANYにローカルアドレスが設定された使用可能な共有ポートにバインドされています...

いくつかの特別なアドレスがあります。INADDR_LOOPBACK(127.0.0.1)は、常にループバックデバイスを介してローカルホストを参照します。INADDR_ANY(0.0.0.0)は、バインド用の任意のアドレスを意味します。

また:

bind()—名前をソケットにバインドします

netinet / in.hで定義されているように、(sin_addr.s_addr)フィールドが定数INADDR_ANYに設定されている場合、呼び出し元は、ソケットがホスト上のすべてのネットワークインターフェイスにバインドされることを要求しています。その後、すべてのインターフェイス(バインドされた名前と一致する)からのUDPパケットとTCP接続がアプリケーションにルーティングされます。これは、サーバーが複数のネットワークにサービスを提供する場合に重要になります。アドレスを指定しないままにすることで、サーバーは、要求が到着したネットワークインターフェイスに関係なく、そのポートに対して行われたすべてのUDPパケットとTCP接続要求を受け入れることができます。


4
「すべてのインターフェースにバインドする」という意味ではありません。その場合、netstatの出力は異なります。これは、「任意のインターフェイスでリッスンする」という意味です。
ローン侯爵

6
上記のリンクを引用すると、「バインド呼び出しでINADDR_ANYが指定されている場合、ソケットはすべてのローカルインターフェイスにバインドされます。」別のリンクから:値「INADDR_ANY」は、ローカルコンピューターが現在持っているすべてのIPアドレスにバインドすることを意味します。しかし、そうです-多くの実装は(「すべて」ではなく)最初のインターフェースにバインドされます。しかし、1つのNICを備えた1台のPCの場合、違いは学術的なものです。INADDR_ANYを使用すると、クライアントは任意の/すべてのIP(たとえば、192.168.1.2と127.0.0.1の両方)に接続できます。
paulsm4 2013年

5
これがばかげた質問なら申し訳ありませんが、インターフェースはワイヤレス、イーサネットなどを意味しますか?
mrQWERTY 2015年

3
@ laike9mローカルマシンからのみソケットに接続できるようにする場合は、127.0.0.1にバインドします。ソケットによって提供されるサービスが、マシンにローカルな別のプロセスによってのみ使用されることを目的としている場合、これの使用例があります。
dgnuff 2015年

2
@ paulsm4 3ではINADDR_LOOPBACK、代わりに、を使用できませんinet_addr("127.0.0.1")か?
John Strood 2016年

62

INADDR_ANYソケットを特定のIPにバインドする必要がない場合に使用されます。を呼び出すときにこの値をアドレスとして使用するとbind()、ソケットはマシンのすべてのIPへの接続を受け入れます。


8

バインドとソケットlocalhostを呼び出します前に、バインド機能、sockaddr_in構造体のsin_addr.s_addrフィールドが適切に設定する必要があります。適切な値は、次のいずれかによって取得できます。

my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1")

またはによって

my_sockaddress.sin_addr.s_addr=htonl(INADDR_LOOPBACK);

4

INADDR_ANY使用可能なすべてのインターフェースにバインドするようにリスニングソケットに指示します。にバインドしようとするのと同じinet_addr("0.0.0.0")です。完全を期すために、IPv6にはIN6ADDR_ANY_INITもあり::、IPv6ソケットのアドレスにバインドしようとするのと同じです。

#include <netinet/in.h>

struct in6_addr addr = IN6ADDR_ANY_INIT;

また、IPv6ソケットをIN6ADDR_ANY_INITソケットにバインドすると、すべてのIPv6インターフェイスにバインドされ、IPv4クライアントからの接続も受け入れることができるはずです(ただし、IPv6にマップされたアドレス)。


2

INADDR_ANYは定数であり、値に0が含まれます。これは、ip-addを気にしないすべてのアクティブなポートから接続する場合にのみ使用されます。したがって、特定のIPを接続する場合は、my_sockaddress.sin_addr.s_addr = inet_addr( "192.168.78.2")のように言及する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.