Comprensione di INADDR_ANY per la programmazione dei socket


86

Sto provando a programmare dei socket e quindi, lato server, lo utilizzo htonl(INADDR_ANY). Per quanto ho capito, mi sembra che questa funzione generi un IP casuale (ho ragione?). In effetti, voglio associare la mia presa con la mia localhost. Ma se eseguo questo

Ottengo 0 come valore di ritorno. Qualcuno potrebbe portare qualche spiegazione?


10
" ... Io uso htonl(INADDR_ANY). Il documento dice che questa funzione genera un IP casuale ... " Questo non è corretto. Quale documento te lo dice?
alk

1
@alk, infatti mi inganno: stavo leggendo dei pdf che pensavo fossero una documentazione ufficiale.
Modifico

Risposte:


137
  1. bind()di INADDR_ANYfa NOT "generare un IP casuale". Esso lega la presa di tutte le interfacce disponibili .

  2. Per un server, in genere si desidera eseguire il binding a tutte le interfacce, non solo a "localhost".

  3. Se desideri associare il tuo socket solo a localhost, la sintassi sarebbe my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1");, quindi chiama bind(my_socket, (SOCKADDR *) &my_sockaddr, ...).

  4. Come succede, INADDR_ANYè una costante che sembra essere uguale a "zero":

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

  5. Se non lo conosci già, ti esorto a consultare la Guida alla programmazione dei socket di Beej:

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

Poiché le persone stanno ancora leggendo questo, una nota aggiuntiva:

uomo (7) ip :

Quando un processo desidera ricevere nuovi pacchetti o connessioni in arrivo, deve associare un socket a un indirizzo di interfaccia locale utilizzando bind (2) .

In questo caso, solo un socket IP può essere associato a una determinata coppia locale (indirizzo, porta). Quando INADDR_ANY è specificato nella chiamata di bind, il socket verrà associato a tutte le interfacce locali.

Quando listen (2) viene chiamato su un socket non associato, il socket viene automaticamente associato a una porta libera casuale con l'indirizzo locale impostato su INADDR_ANY.

Quando connect (2) viene chiamato su un socket non associato, il socket viene automaticamente associato a una porta libera casuale oa una porta condivisa utilizzabile con l'indirizzo locale impostato su INADDR_ANY ...

Esistono diversi indirizzi speciali: INADDR_LOOPBACK (127.0.0.1) si riferisce sempre all'host locale tramite il dispositivo di loopback; INADDR_ANY (0.0.0.0) indica qualsiasi indirizzo per l'associazione ...

Anche:

bind () - Associa un nome a un socket :

Se il campo (sin_addr.s_addr) è impostato sulla costante INADDR_ANY, come definito in netinet / in.h, il chiamante richiede che il socket sia associato a tutte le interfacce di rete sull'host. Successivamente, i pacchetti UDP e le connessioni TCP da tutte le interfacce (che corrispondono al nome associato) vengono instradati all'applicazione. Ciò diventa importante quando un server offre un servizio a più reti. Lasciando l'indirizzo non specificato, il server può accettare tutti i pacchetti UDP e le richieste di connessione TCP effettuate per la sua porta, indipendentemente dall'interfaccia di rete su cui sono arrivate le richieste.


4
Non significa "legare a tutte le interfacce". Se lo facesse, l'output di netstat sarebbe diverso. Significa "ascolta su qualsiasi interfaccia".
user207421

7
Per citare il collegamento precedente: "Quando INADDR_ANY è specificato nella chiamata di associazione, il socket verrà associato a tutte le interfacce locali." Da un altro collegamento: Il valore "INADDR_ANY" significa che ci collegheremo a qualsiasi / tutti gli indirizzi IP che il computer locale ha attualmente . Ma sì, molte implementazioni si legheranno alla prima interfaccia, (non "tutte"). Ma per un PC con una scheda NIC, la differenza è accademica. Con INADDR_ANY, il client può connettersi a qualsiasi / tutti gli IP (ad esempio sia 192.168.1.2 che 127.0.0.1).
paulsm4

6
Scusa se questa è una domanda stupida, ma l'interfaccia significa wireless, ethernet, ecc.?
mrQWERTY

3
@ laike9m Ti legheresti a 127.0.0.1 quando vuoi essere in grado di connetterti al socket solo dalla macchina locale. Ci sono casi d'uso per questo quando il servizio offerto dal socket è inteso solo per essere utilizzato da un altro processo locale alla macchina.
Dgnuff

2
@ paulsm4 In 3, non puoi usare INADDR_LOOPBACK, invece di inet_addr("127.0.0.1")?
John Strood

63

INADDR_ANYviene utilizzato quando non è necessario associare un socket a un IP specifico. Quando si utilizza questo valore come indirizzo durante la chiamata bind(), il socket accetta connessioni a tutti gli IP della macchina.


8

Per associare socket con localhost , prima di richiamare la funzione bind , il campo sin_addr.s_addr della struttura sockaddr_in dovrebbe essere impostato correttamente. Il valore corretto può essere ottenuto sia da

o da


4

INADDR_ANYindica al socket in ascolto di collegarsi a tutte le interfacce disponibili. È lo stesso che cercare di legarsi a inet_addr("0.0.0.0"). Per completezza menzionerò anche che c'è anche IN6ADDR_ANY_INIT per IPv6 ed è lo stesso che provare a collegarsi ::all'indirizzo per il socket IPv6.

Inoltre, tieni presente che quando colleghi il socket IPv6 al IN6ADDR_ANY_INITtuo socket, si collegherà a tutte le interfacce IPv6 e dovrebbe essere in grado di accettare anche connessioni da client IPv4 (sebbene indirizzi mappati IPv6).


2

INADDR_ANY è una costante, che contiene 0 in valore. questo verrà usato solo quando vuoi connetterti da tutte le porte attive che non ti interessano ip-add. quindi se vuoi connettere un IP particolare dovresti menzionare come my_sockaddress.sin_addr.s_addr = inet_addr ("192.168.78.2")

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.