私はいくつかのソケットをプログラムしようとしているので、サーバー側ではhtonl(INADDR_ANY)
を使用します。私が理解した範囲では、この関数はランダムIPを生成するように思えます(私は正しいですか?)。実際、ソケットをlocalhost
にバインドしたいと思います。しかし、これを実行すると
printf("%d",htonl(INADDR_ANY));
戻り値として0を取得します。誰かが説明をすることができますか?
bind()
of INADDR_ANY
はではなく「ランダムIPを生成」します。それ 利用可能なすべてのインターフェースにソケットをバインドします 。
サーバーの場合、通常は「localhost」だけでなく、すべてのインターフェースにバインドします。
ソケットをローカルホストのみにバインドする場合、構文はmy_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1");
になり、bind(my_socket, (SOCKADDR *) &my_sockaddr, ...)
を呼び出します。
それが起こると、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
...
慣れていない場合は、Beejのソケットプログラミングガイドを参照することをお勧めします。
人々はまだこれを読んでいるので、追加のメモ:
man(7)ip :
プロセスは、新しい着信パケットまたは接続を受信する場合、 bind(2) を使用してソケットをローカルインターフェイスアドレスにバインドする必要があります。
この場合、特定のローカル(アドレス、ポート)ペアにバインドできるIPソケットは1つだけです。バインド呼び出しでINADDR_ANYが指定されている場合、ソケットはすべてのローカルインターフェイスにバインドされます。
listen(2) が非バインドソケットで呼び出されると、ソケットはローカルアドレスがINADDR_ANYに設定されたランダムな空きポートに自動的にバインドされます。
connect(2) が非バインドソケットで呼び出されると、ソケットは自動的にランダムな空きポートまたはローカルアドレスがINADDR_ANYに設定された使用可能な共有ポートにバインドされます...
いくつかの特別なアドレスがあります:INADDR_LOOPBACK(127.0.0.1)は常にループバックデバイスを介してローカルホストを参照します。 INADDR_ANY(0.0.0.0)は、バインドするアドレスを意味します...
また:
(sin_addr.s_addr)フィールドがnetinet/in.hで定義されているように、定数INADDR_ANYに設定されている場合、呼び出し元はソケットがホスト上のすべてのネットワークインターフェイスにバインドされることを要求しています。その後、すべてのインターフェイス(バインドされた名前と一致する)からのUDPパケットとTCP接続がアプリケーションにルーティングされます。これは、サーバーが複数のネットワークにサービスを提供するときに重要になります。アドレスを指定しないままにしておくと、サーバーは、要求が到着したネットワークインターフェイスに関係なく、そのポートに対して行われたすべてのUDPパケットとTCP接続要求を受け入れることができます。
INADDR_ANY
は、ソケットを特定のIPにバインドする必要がない場合に使用されます。 bind()
を呼び出すときにこの値をアドレスとして使用すると、ソケットはマシンのすべてのIPへの接続を受け入れます。
bindソケットとlocalhostを組み合わせて、bind関数を呼び出す前に、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);
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にマップされたアドレス)。
INADDR_ANYは定数で、valueに0が含まれます。これは、ip-addを気にしないすべてのアクティブなポートから接続する場合にのみ使用されます。したがって、特定のIPを接続する場合は、my_sockaddress.sin_addr.s_addr = inet_addr( "192.168.78.2")のように言及する必要があります。