Verständnis von INADDR_ANY für die Socket-Programmierung

Lesezeit: 7 Minuten

Benutzeravatar von epsilones
epsilone

Ich versuche, einige Sockets zu programmieren, und verwende sie auf der Serverseite htonl(INADDR_ANY). Soweit ich das verstanden habe, scheint mir diese Funktion eine zufällige IP zu generieren (liege ich richtig?). Tatsächlich möchte ich meine Steckdose mit meiner binden localhost. Aber wenn ich das laufe

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

Als Rückgabewert bekomme ich 0. Könnte jemand eine Erklärung bringen?

  • … Ich benutze htonl(INADDR_ANY). Das Dokument sagt, dass diese Funktion eine zufällige IP generiert …“Das ist nicht korrekt. Welche Dokumente sagen Ihnen das?

    – alk

    12. Mai 2013 um 15:06 Uhr


  • @alk, tatsächlich habe ich irregeführt: Ich habe ein PDF gelesen, von dem ich dachte, dass es sich um eine offizielle Dokumentation handelt. Ich editiere meinen Beitrag jetzt

    – Epsilone

    12. Mai 2013 um 20:06 Uhr

Benutzeravatar von paulsm4
paulsm4

  1. bind() von INADDR_ANY tut NICHT “Erzeuge eine zufällige IP”. Es bindet den Socket an alle verfügbaren Schnittstellen.

  2. Bei einem Server möchten Sie normalerweise alle Schnittstellen binden – nicht nur „localhost“.

  3. Wenn Sie Ihren Socket nur an localhost binden möchten, wäre die Syntax my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1");Dann ruf an bind(my_socket, (SOCKADDR *) &my_sockaddr, ...).

  4. Wie es passiert, INADDR_ANY ist eine Konstante, die zufällig gleich “Null” ist:

    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. Wenn Sie damit noch nicht vertraut sind, empfehle ich Ihnen dringend, sich Beejs Guide to Sockets Programming anzusehen:

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

Da dies immer noch gelesen wird, eine zusätzliche Anmerkung:

Mann (7) ip:

Wenn ein Prozess neue eingehende Pakete oder Verbindungen empfangen möchte, sollte er einen Socket mit einer lokalen Schnittstellenadresse binden binden(2).

In diesem Fall kann nur ein IP-Socket an ein bestimmtes lokales Paar (Adresse, Port) gebunden werden. Wenn INADDR_ANY im Bindeaufruf angegeben wird, wird der Socket an alle lokalen Schnittstellen gebunden.

Wann zuhören(2) auf einem ungebundenen Socket aufgerufen wird, wird der Socket automatisch an einen zufälligen freien Port gebunden, wobei die lokale Adresse auf INADDR_ANY gesetzt ist.

Wann verbinden(2) auf einem ungebundenen Socket aufgerufen wird, wird der Socket automatisch an einen zufälligen freien Port oder an einen verwendbaren gemeinsam genutzten Port gebunden, wobei die lokale Adresse auf INADDR_ANY gesetzt ist …

Es gibt mehrere spezielle Adressen: INADDR_LOOPBACK (127.0.0.1) verweist immer auf den lokalen Host über das Loopback-Gerät; INADDR_ANY (0.0.0.0) bedeutet eine beliebige Adresse zum Binden …

Ebenfalls:

bind() — Binden Sie einen Namen an einen Socket:

Wenn das Feld (sin_addr.s_addr) auf die Konstante INADDR_ANY gesetzt ist, wie in netinet/in.h definiert, fordert der Aufrufer an, dass der Socket an alle Netzwerkschnittstellen auf dem Host gebunden wird. Anschließend werden UDP-Pakete und TCP-Verbindungen von allen Schnittstellen (die mit dem gebundenen Namen übereinstimmen) an die Anwendung weitergeleitet. Dies wird wichtig, wenn ein Server mehreren Netzwerken einen Dienst anbietet. Indem die Adresse nicht angegeben wird, kann der Server alle UDP-Pakete und TCP-Verbindungsanfragen akzeptieren, die für seinen Port gestellt werden, unabhängig von der Netzwerkschnittstelle, auf der die Anfragen angekommen sind.

  • Es bedeutet nicht “an alle Schnittstellen binden”. Wenn dies der Fall wäre, wäre die netstat-Ausgabe anders. Es bedeutet „zuhören“. irgendein Schnittstelle’.

    – Benutzer207421

    12. Mai 2013 um 22:09 Uhr

  • Um den obigen Link zu zitieren: “Wenn INADDR_ANY im Bind-Aufruf angegeben ist, wird der Socket an alle lokalen Schnittstellen gebunden.” Aus einem anderen Link: Der Wert „INADDR_ANY“ bedeutet, dass wir an beliebige/alle IP-Adressen binden, die der lokale Computer derzeit hat. Aber ja – viele Implementierungen werden binden Der Erste Schnittstelle, (nicht “alle”). Aber für einen PC mit einer NIC ist der Unterschied akademisch. Mit INADDR_ANY kann sich der Client mit beliebigen/allen IPs verbinden (z. B. sowohl 192.168.1.2 als auch 127.0.0.1).

    – paulsm4

    13. Mai 2013 um 3:40 Uhr


  • Entschuldigung, wenn dies eine dumme Frage ist, aber bedeutet Schnittstelle WLAN, Ethernet usw.?

    – mrQWERTY

    18. März 2015 um 3:36 Uhr

  • @ laike9m Sie würden an 127.0.0.1 binden, wenn Sie nur vom lokalen Computer aus eine Verbindung zum Socket herstellen möchten. Es gibt Anwendungsfälle dafür, wenn der vom Socket angebotene Dienst nur von einem anderen Prozess verwendet werden soll, der lokal auf der Maschine ist.

    – dgnuff

    8. Oktober 2015 um 22:29 Uhr

  • @paulsm4 In 3 kannst du nicht verwenden INADDR_LOOPBACKAnstatt von inet_addr("127.0.0.1") ?

    – John Strood

    30. Oktober 2016 um 9:54 Uhr

INADDR_ANY wird verwendet, wenn Sie einen Socket nicht an eine bestimmte IP binden müssen. Wenn Sie diesen Wert als Adresse beim Anruf verwenden bind()akzeptiert der Socket Verbindungen zu allen IPs der Maschine.

Zu binden Steckdose mit lokaler Hostbevor Sie die aufrufen binden Funktion sollte das Feld sin_addr.s_addr der Struktur sockaddr_in richtig eingestellt sein. Der richtige Wert kann entweder durch erhalten werden

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

oder von

my_sockaddress.sin_addr.s_addr=htonl(INADDR_LOOPBACK);

Benutzeravatar von Pavel P
Paul P

INADDR_ANY weist das lauschende Socket an, sich an alle verfügbaren Schnittstellen zu binden. Es ist dasselbe wie zu versuchen, sich daran zu binden inet_addr("0.0.0.0"). Der Vollständigkeit halber erwähne ich auch, dass es das auch gibt IN6ADDR_ANY_INIT für IPv6 und es ist dasselbe wie der Versuch, eine Bindung herzustellen :: Adresse für IPv6-Socket.

#include <netinet/in.h>

struct in6_addr addr = IN6ADDR_ANY_INIT;

Beachten Sie auch, dass beim Binden des IPv6-Sockets an IN6ADDR_ANY_INIT Ihr Socket bindet an alle IPv6-Schnittstellen und sollte auch Verbindungen von IPv4-Clients akzeptieren können (obwohl IPv6-zugeordnete Adressen).

Benutzeravatar von Lewis Kelsey
Lewis Kelsey

Wenn Sie einen Server haben, erstellen Sie einen Socket und binden ihn dann an eine IP und einen Port, wodurch der Socket anhand eines eindeutigen Socket-Typs, einer Adressfamilie, einer IP und eines Ports eindeutig identifiziert werden kann. Sie hören dann(), um den Socket in den Servermodus zu versetzen, und dann akzeptieren Sie(), das auf eine Verbindung wartet, die eingehende Pakete mit Ziel-IP/-Port enthält, die dazu führen, dass die Pakete auf diesem Socket in die Warteschlange gestellt werden. Sie müssen es jedoch nicht an eine IP binden, es kann Verbindungen auf allen Schnittstellen akzeptieren.

Wenn Sie einen Client haben, erstellen Sie einen Socket und verbinden () den Socket mit einer Remote-IP und einem Remote-Port, wodurch auch 0.0.0.0 und ein zufälliger unbenutzter kurzlebiger Port an den Socket gebunden werden, falls er noch nicht gebunden wurde zu einer IP und einem Port mit bind(INADDR_ANY, 0). connect() gibt zurück, wenn es eine Verbindung herstellt, und verwendet die IP und den Port als Quelladresse in den ausgehenden Paketen, wobei 0.0.0.0 immer durch eine IP ersetzt wird, die auf dem src-Hinweis in der Routing-Tabelle oder der IP der ausgewählten Schnittstelle (falls es hat mehrere IPs, dann wird die erste IP mit gleichem oder größerem Umfang ausgewählt), und dann verwenden Sie sendall, um Anwendungsdaten zu senden.

INADDR_ANY ist schneller als das programmgesteuerte Erfassen der aktuellen internen IP der Schnittstelle, die sich jederzeit ändern kann, und Pakete werden nicht mehr auf dem Port empfangen, aber sie würden immer noch auf 0.0.0.0 empfangen, da es sich um eine beliebige Adresse handelt.

Beachten Sie, dass ein Socket an 0.0.0.0 gebunden werden kann, aber nicht an Port 0, da es sich um einen Platzhalter handelt, der dem Socket einen zufälligen kurzlebigen Port gibt. Wenn Sie also bind(INADDR_ANY, 0) verwenden, wird es an 0.0.0.0 und a gebunden zufälliger ephemerer Port.

viveks Benutzeravatar
vivek

INADDR_ANY ist eine Konstante, deren Wert 0 enthält. Dies wird nur verwendet, wenn Sie eine Verbindung von allen aktiven Ports herstellen möchten, für die Sie sich nicht interessieren ip-add . Wenn Sie also eine bestimmte IP-Adresse verbinden möchten, sollten Sie Folgendes erwähnen: my_sockaddress.sin_addr.s_addr = inet_addr (“192.168.78.2”)

Benutzeravatar von Suraj Rao
Suraj Rao

#include <arpa/inet.h>                                                                     
.                                                                                   
.                                                                                        
tcpsock.sin_addr.s_addr = inet_addr("192.168.1.2")

hat bei mir funktioniert

1421530cookie-checkVerständnis von INADDR_ANY für die Socket-Programmierung

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy