InADDR_ANY voor socketprogrammering begrijpen

Ik probeer enkele sockets te programmeren en daarom gebruik ik aan de serverkant htonl(INADDR_ANY). Voor zover ik het begreep, lijkt het mij dat deze functie een willekeurig IP-adres genereert (heb ik gelijk?). In feite wil ik mijn socket binden met mijn localhost. Maar als ik dit

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

Ik krijg 0 als retourwaarde. Kan iemand wat uitleg geven?


Antwoord 1, autoriteit 100%

  1. bind() van INADDR_ANY doet NIET “een willekeurig IP-adres genereren”. Het bindt de socket aan alle beschikbare interfaces.

  2. Voor een server wil je normaal gesproken aan alle interfaces binden – niet alleen “localhost”.

  3. Als u uw socket alleen aan localhost wilt binden, is de syntaxis my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1");, en roept u vervolgens bind(my_socket, (SOCKADDR *) &my_sockaddr, ...).

  4. Het toeval wil dat INADDR_ANY een constante is die toevallig gelijk is aan “nul”:

    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. Als je er nog niet bekend mee bent, raad ik je aan om Beej’s Guide to Sockets Programming te lezen:

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

Omdat mensen dit nog steeds lezen, een aanvullende opmerking:

man (7) ip:

Als een proces nieuwe inkomende pakketten of verbindingen wil ontvangen,
het zou een socket moeten binden aan een lokaal interface-adres met behulp van bind(2).

In dit geval mag er slechts één IP-socket aan een bepaalde local worden gebonden
(adres, poort) paar. Wanneer INADDR_ANY is opgegeven in de bind-aanroep,
de socket is gebonden aan alle lokale interfaces.

Wanneer listen(2) wordt aangeroepen op een ongebonden stopcontact, het stopcontact is:
automatisch gebonden aan een willekeurige vrije poort met het lokale adres ingesteld
naar INADDR_ANY.

Wanneer connect(2) wordt aangeroepen op een ongebonden stopcontact, het stopcontact is:
automatisch gebonden aan een willekeurige vrije poort of aan een bruikbare gedeelde poort
met het lokale adres ingesteld op INADDR_ANY…

Er zijn verschillende speciale adressen: INADDR_LOOPBACK (127.0.0.1)
verwijst altijd naar de lokale host via het loopback-apparaat; INADDR_ANY
(0.0.0.0) betekent elk adres voor binding…

Ook:

bind( ) Bind een naam aan een
stopcontact
:

Als het veld (sin_addr.s_addr) is ingesteld op de constante INADDR_ANY, zoals
gedefinieerd in netinet/in.h, vraagt ​​de beller om de socket
gebonden aan alle netwerkinterfaces op de host. Vervolgens UDP-pakketten
en TCP-verbindingen van alle interfaces (die overeenkomen met de gebonden naam)
worden doorgestuurd naar de applicatie. Dit wordt belangrijk wanneer een server
biedt een dienst aan meerdere netwerken. Door het adres achter te laten
niet gespecificeerd, de server kan alle UDP-pakketten en TCP-verbindingen accepteren
verzoeken om zijn poort, ongeacht de netwerkinterface op
waarop de verzoeken zijn binnengekomen.


Antwoord 2, autoriteit 43%

INADDR_ANY wordt gebruikt wanneer u een socket niet aan een specifiek IP-adres hoeft te binden. Wanneer u deze waarde als adres gebruikt bij het aanroepen van bind(), accepteert de socket verbindingen met alle IP’s van de machine.


Antwoord 3, autoriteit 6%

Om een ​​socket te binden met localhost, voordat je de functie bind aanroept, moet het veld sin_addr.s_addr van de structuur sockaddr_in correct worden ingesteld. De juiste waarde kan worden verkregen door

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

of door

my_sockaddress.sin_addr.s_addr=htonl(INADDR_LOOPBACK);

Antwoord 4, autoriteit 3%

INADDR_ANY geeft de luistersocket de opdracht om te binden aan alle beschikbare interfaces. Het is hetzelfde als proberen te binden aan inet_addr("0.0.0.0").
Voor de volledigheid vermeld ik ook dat er ook IN6ADDR_ANY_INIT voor IPv6 is en het is hetzelfde als proberen te binden aan het ::-adres voor de IPv6-socket.

#include <netinet/in.h>
struct in6_addr addr = IN6ADDR_ANY_INIT;

Houd er ook rekening mee dat wanneer u IPv6-socket bindt aan IN6ADDR_ANY_INIT uw socket bindt aan alle IPv6-interfaces en ook verbindingen van IPv4-clients moet kunnen accepteren (hoewel IPv6-toegewezen adressen) .


Antwoord 5

INADDR_ANY is een constante, die 0 bevat in waarde . dit wordt alleen gebruikt als u verbinding wilt maken vanaf alle actieve poorten die u niet interesseren ip-add .
dus als je een bepaald IP-adres wilt verbinden, moet je het vermelden als:
my_sockaddress.sin_addr.s_addr = inet_addr(“192.168.78.2”)


Antwoord 6

Als je een server hebt, maak je een socket en bind je deze aan een IP en poort, waardoor de socket een unieke manier krijgt om geïdentificeerd te worden op basis van een uniek sockettype, adresfamilie, IP en poort. Je luistert dan () om de socket in de servermodus te zetten, en dan accepteer je (), die wacht op een verbinding die inkomende pakketten zal hebben met doelparameters die ervoor zorgen dat de pakketten in de wachtrij worden geplaatst op die socket.

Als je een client hebt, maak je een socket en verbind je () de socket met een externe IP en poort, die ook 0.0.0.0 en een willekeurige ongebruikte tijdelijke poort aan de socket bindt als dat niet het geval is is al gebonden aan een IP en poort met behulp van bind (INADDR_ANY, 0). connect() keert terug wanneer het verbinding maakt en gebruikt het IP en de poort als het bronadres in de uitgaande pakketten, waarbij 0.0.0.0 altijd wordt vervangen door het huidige interne IP door het besturingssysteem, en dan gebruik je sendall om applicatiegegevens te verzenden.

INADDR_ANY is sneller dan het programmatisch verkrijgen van het huidige interne IP-adres van de computer, dat op elk moment kan veranderen, en pakketten worden niet langer op de poort ontvangen, maar ze zouden nog steeds worden ontvangen op 0.0.0.0 omdat het een adres.

Houd er rekening mee dat een socket kan worden gebonden aan 0.0.0.0, maar niet aan poort 0, omdat het een jokerteken is waardoor het de socket een willekeurige tijdelijke poort geeft, dus als je bind (INADDR_ANY, 0) gebruikt, wordt het gebonden aan 0.0. 0.0 en een willekeurige tijdelijke poort.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes