Christian Seiler: C++: Problem mit bind()

Beitrag lesen

Hallo Klaus,

"Error: binding server socket bind(); Cannot assign requested address"

Und wird wie man sieht, von bind() verursacht. Was ist falsch?

Du musst srv_addr auch korrekt initialisieren. Du gibst hier nur den Port, nicht jedoch die Adresse an (die Adresse kann entweder die Adresse eines Interfaces sein oder eine spezielle Konstante für "JEDES INTERFACE") - und einige andere Optionen für IPv6 gibst Du auch nicht an.

In IPv4 hat laut der Manual-Seite ip(7) die Struktur sockaddr_in folgende Einträge:

         struct sockaddr_in {  
             sa_family_t    sin_family; /* address family: AF_INET */  
             u_int16_t      sin_port;   /* port in network byte order */  
             struct in_addr sin_addr;   /* internet address */  
         };

Wenn Du den korrekt initialisieren willst, musst Du folgendes machen:

struct sockaddr_in srv_addr;  
srv_addr.sin_family = AF_INET;  
srv_addr.sin_port = ...; // z.B. 80  
srv_addr.sin_addr.s_addr = INADDR_ANY

In IPv6 (laut Manpage ipv6(7)) besitzt ein paar mehr Einträge:

              struct sockaddr_in6 {  
                  u_int16_t       sin6_family;/* AF_INET6 */  
                  u_int16_t       sin6_port;/* port number */  
                  u_int32_t       sin6_flowinfo;/* IPv6 flow information */  
                  struct in6_addr sin6_addr;/* IPv6 address */  
                  u_int32_t   sin6_scope_id;  /* Scope ID (new in 2.4) */  
              };

sin6_flowinfo und sin6_scope_id: Wenn Du nicht weiß, was das macht, dann setze es am besten auf 0. Zudem kann es keine Konstante INADDR_ANY mehr geben, weil viele Prozessoren noch keine 128bit großen Werte unterstützen - dafür gibt's jetzt die Variable in6addr_any, die Du stattdessen verwenden kannst. Die Struktur musst Du also so korrekt initialisieren:

struct sockaddr_in6 srv_addr;  
srv_addr.sin6_family = AF_INET6;  
srv_addr.sin6_port = ...; // z.B. 80  
srv_addr.sin6_flowinfo = 0;  
srv_addr.sin6_addr = in6addr_any;  
srv_addr.sin6_scope_id = 0;

Wenn Du Dich nicht an ALLE Interfaces binden willst, sondern nur an bestimmte, dann fängt die sin6_scope_id an, relevant zu werden, sprich: Dann müsstest Du Dich anfangen, mit den Details von IPv6 zu beschäftigen, weil es in Bezug Interfaces komplizierter ist, als IPv4.

Achja, evtl. hilfreich: http://www.ularx.de/studies/porting2ipv6.html

Als letztes habe ich den Code von IPv4 auf IPv6 umgerüstet. Bis dahin lief der Code einwandfrei. Habe ich was übersehen, was falsch gemacht?

Auch bei IPv4 war der Code schon fehlerhaft, da war's Zufall, dass es trotzdem funktioniert hat.

Viele Grüße,
Christian