2014-05-01 26 views
15

Z tego co rozumiem struct addrinfo służy do przygotowania struktury adresu gniazda, a struct sockaddr zawiera informacje o adresie gniazda. Ale co to właściwie znaczy? struct addrinfo zawiera wskaźnik do struct sockaddr. Dlaczego trzymasz je oddzielnie? Dlaczego nie możemy połączyć wszystkich rzeczy w sockaddr w addr_info?Jaka jest różnica między struct addrinfo a struct sockaddr

Po prostu zgaduję, ale czy powodem ich separacji jest zaoszczędzić miejsce przy przechodzeniu przez struktury? Na przykład w wywołaniu funkcji bind() wszystko, czego potrzebuje, to numer portu i adres internetowy. Więc oba z nich są zgrupowane w struct sockaddr. Tak, możemy po prostu przekazać tę małą strukturę zamiast większych struct addrinfo?

struct addrinfo { 
    int    ai_flags;  // AI_PASSIVE, AI_CANONNAME, etc. 
    int    ai_family; // AF_INET, AF_INET6, AF_UNSPEC 
    int    ai_socktype; // SOCK_STREAM, SOCK_DGRAM 
    int    ai_protocol; // use 0 for "any" 
    size_t   ai_addrlen; // size of ai_addr in bytes 
    struct sockaddr *ai_addr;  // struct sockaddr_in or _in6 
    char   *ai_canonname; // full canonical hostname 

    struct addrinfo *ai_next;  // linked list, next node 
}; 

struct sockaddr { 
    unsigned short sa_family; // address family, AF_xxx 
    char    sa_data[14]; // 14 bytes of protocol address 
}; 

Odpowiedz

12

struct addrinfo jest zwracany przez getaddrinfo() i zawiera, w przypadku sukcesu, połączonej listy takich struct s dla określonego hosta i/lub usługi.

Człon ai_addr nie jest faktycznie struct sockaddr, bo struct jest jedynie ogólny, który zawiera wspólne dla wszystkich członków innych, i jest stosowany w celu określenia, jakiego rodzaju struktury faktycznie mają. W zależności od tego, co przekazałeś do getaddrinfo(), i co ta funkcja dowiodła, może być w rzeczywistości wskaźnikiem na struct sockaddr_in lub struct sockaddr_in6 lub cokolwiek innego, w zależności od tego, co jest właściwe dla tego konkretnego wpisu adresu. Jest to jeden dobry powód, dla którego są one przechowywane "osobno", ponieważ ten użytkownik może wskazywać na jeden z wielu różnych typów struct s, których nie mógłby zrobić, gdybyś próbował zaszyfrować wszystkich członków do struct addrinfo, ponieważ te różne struct s mają różnych członków.

Jest to prawdopodobnie najprostszy sposób na uzyskanie tych informacji, jeśli masz nazwę hosta, ale nie jest to jedyny sposób. W przypadku połączenia IPv4 można po prostu zapełnić strukturę struct sockaddr_in, jeśli chcesz, i masz dane, aby to zrobić, i unikaj przechodzenia przez rigamarole wywoływania getaddrinfo(), na którą możesz czekać, jeśli musi wyjść. do Internetu, aby zebrać informacje dla ciebie. W ogóle nie musisz używać struct addrinfo.

+0

to getaddrinfo() również bardziej przydatne, jeśli znasz tylko nazwę hosta, a nie adres IP hosta? Ponieważ wydaje się być trochę powtarzalnym, jeśli jesteś klientem (i znasz IP serwera) i wywołujesz getaddrinfo i wysyłasz adres IP serwera, a getaddrinfo() zwraca strukturę addrinfo ze wszystkimi szczegółami, które już znasz? ten komentarz musi być po prostu powtórzeniem tego, co powiedziałeś ..sorry – user68212

+0

'getaddrinfo()' jest czasami wygodne, jeśli masz adres IP w ciągu * * - powiedz po wprowadzeniu go w wierszu poleceń. Możesz sam go sparsować i przenieść do 32-bitowego, integralnego formatu wymaganego przez 'struct sockaddr_in', ale czasami możesz stwierdzić, że łatwiej jest' getaddrinfo() 'zrobić to za ciebie. Jeśli masz już adres IP w formacie, który możesz wpaść do 'struct sockaddr_in', wywołanie' getaddrinfo() 'zwykle będzie bezsensowne. –

Powiązane problemy