소켓 프로그래밍을위한 INADDR_ANY 이해


84

일부 소켓을 프로그래밍하려고하므로 서버 측에서 htonl(INADDR_ANY). 내가 이해하는 한,이 함수는 임의의 IP를 생성하는 것 같습니다 (제가 맞습니까?). 사실, 내 소켓을 localhost. 하지만 내가 이것을 실행하면

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

반환 값으로 0을 얻습니다. 누군가 설명을 할 수 있습니까?


9
" ... 나는를 사용합니다 htonl(INADDR_ANY).이 함수는 임의의 IP를 생성한다고 문서에 나와 있습니다 ... "이것은 올바르지 않습니다. 어떤 문서가 그렇게 말합니까?
ALK

1
@alk, 사실 나는 오도했다 : 나는 공식 문서라고 생각한 pdf를 읽고 있었다. 지금은 내 게시물을 편집
epsilones

답변:


132
  1. bind()의 "임의의 IP를 생성" INADDR_ANY하지 않습니다 . 그것은 가능한 모든 인터페이스에 소켓을 바인드합니다 .

  2. 서버의 경우 일반적으로 "localhost"뿐 아니라 모든 인터페이스에 바인딩하려고합니다.

  3. 소켓을 localhost에만 바인딩하려는 경우 구문은 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/

사람들이 여전히 이것을 읽고 있으므로 추가 메모 :

남자 (7) ip :

프로세스가 새로운 수신 패킷이나 연결을 수신하려면 bind (2)를 사용하여 소켓을 로컬 인터페이스 주소에 바인딩해야합니다 .

이 경우 하나의 IP 소켓 만 주어진 로컬 (주소, 포트) 쌍에 바인딩 될 수 있습니다. INADDR_ANY가 바인드 호출에 지정되면 소켓은 모든 로컬 인터페이스에 바인드됩니다.

들을(2) 언 바운드 소켓이라고, 소켓이 자동으로 INADDR_ANY 로컬 주소 세트를 임의의 사용 가능한 포트에 바인딩됩니다.

연결할(2) 언 바운드 소켓이라고, 소켓이 자동으로 임의의 사용 가능한 포트 또는 INADDR_ANY 로컬 주소를 세트로 사용 가능한 공유 포트에 바인딩 ...

몇 가지 특수 주소가 있습니다. INADDR_LOOPBACK (127.0.0.1)은 항상 루프백 장치를 통해 로컬 호스트를 참조합니다. INADDR_ANY (0.0.0.0)는 바인딩 할 주소를 의미합니다.

또한:

bind () — 이름을 소켓에 바인드 :

(sin_addr.s_addr) 필드가 netinet / in.h에 정의 된 상수 INADDR_ANY로 설정되면 호출자는 소켓이 호스트의 모든 네트워크 인터페이스에 바인딩되도록 요청합니다. 그 후 모든 인터페이스 (바인드 된 이름과 일치)의 UDP 패킷 및 TCP 연결이 애플리케이션으로 라우팅됩니다. 이것은 서버가 여러 네트워크에 서비스를 제공 할 때 중요합니다. 주소를 지정하지 않은 상태로두면 서버는 요청이 도착한 네트워크 인터페이스에 관계없이 포트에 대한 모든 UDP 패킷 및 TCP 연결 요청을 수락 할 수 있습니다.


4
'모든 인터페이스에 바인딩'을 의미하지는 않습니다. 그렇게하면 netstat 출력이 달라집니다. 그것은 ' 모든 인터페이스 에서 듣기'를 의미 합니다.
Marquis of Lorne

6
위의 링크를 인용하려면 : "바인드 호출에 INADDR_ANY가 지정되면 소켓은 모든 로컬 인터페이스에 바인드됩니다." 다른 링크에서 : "INADDR_ANY"값은 현재 로컬 컴퓨터에있는 모든 IP 주소에 바인딩됨을 의미합니다 . 그러나 그렇습니다. 많은 구현이 첫 번째 인터페이스에 바인딩됩니다 ( "모두"가 아님). 그러나 하나의 NIC가있는 하나의 PC의 경우 차이점은 학문적입니다. INADDR_ANY를 사용하면 클라이언트는 모든 IP (예 : 192.168.1.2 및 127.0.0.1)에 연결할 수 있습니다.
paulsm4 2013 년

5
어리석은 질문이라면 미안하지만 인터페이스는 무선, 이더넷 등을 의미합니까?
mrQWERTY

3
@ laike9m 로컬 컴퓨터에서만 소켓에 연결할 수 있도록하려면 127.0.0.1에 바인딩합니다. 소켓에서 제공하는 서비스가 머신에 로컬 인 다른 프로세스에서만 사용하도록 의도 된 경우에 대한 사용 사례가 있습니다.
dgnuff

2
@ paulsm4 3에서는 INADDR_LOOPBACK대신 사용할 수 inet_addr("127.0.0.1")없습니까?
John Strood

62

INADDR_ANY소켓을 특정 IP에 바인딩 할 필요가 없을 때 사용됩니다. 를 호출 할 때이 값을 주소로 사용 bind()하면 소켓은 컴퓨터의 모든 IP에 대한 연결을 허용합니다.


8

바인드 와 소켓 로컬 호스트 인보 당신 전에 바인드 기능의를 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는 value에 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.