Rzutowanie i wyłuskanie wartości wraz z przypisaniem do zmiennej strukturalnej - winsock

0

Cześć, zacząłem przerabiać temat gniazd. Nie mogę zrozumieć jednej instrukcji. Proszę o pomoc.
Mamy strukturę sockaddr_in:

typedef struct sockaddr_in {
short sin_family;
 unsigned short sin_port;
IN_ADDR sin_addr;
CHAR sin_zero[8];
} SOCKADDR_IN, *PSOCKADDR_IN;

pole sin_addr tej struktury, to również struktura:

typedef struct in_addr {
 union {
 struct {
 UCHAR s_b1, s_b2, s_b3,
s_b4;
 } S_un_b;
 struct {
 USHORT s_w1,s_w2;
 } S_un_w;
 ULONG S_addr;
 } S_un;
} IN_ADDR, *PIN_ADDR, *LPIN_ADDR;

Mamy również wskaźnik na strukturę hostens:

hostent* h = gethostbyname("google.pl”);

A tu jej definicja:

struct hostent {
               char  *h_name;            /* official name of host */
               char **h_aliases;         /* alias list */
               int    h_addrtype;        /* host address type */
               int    h_length;          /* length of address */
               char **h_addr_list;       /* list of addresses */
           }
           #define h_addr h_addr_list[0] /* for backward compatibility */

I teraz instrukcja, której nie rozumiem:

service.sin_addr =
 *(struct in_addr*)h->h_addr_list[0];

service została zadeklarowana jako: sockaddr_in service;
h_addr_list_[0]- jest łańcuchem znakowym

Co właściwie próbuję przypisać zmiennej strukturalnej sin_addr będącej polem zmiennej strukturalnej service?
W tym miejscu wskaźnik na strukturę h jest rzutowany na wskaźnik na strukturę in_addr.
A jaką wartość próbuję wyłuskać operatorem dereferencji po znaku przypisania? Skoro byłaby to wartość h_addr_list[0], to typ struktury sin_addr nie zgadzałby się z typem będącym adresem "tylko" łańcucha znakowego. Jak mam rozumieć to rzutowanie? A jeśli było by to przypisanie wartości rzutowanej zmiennej strukturalnej do zmiennej strukturalnej innego typu to po co odwołanie do łańcucha znakowego h_addr_list[0]?

2

h_addr_list_[0] - jest łańcuchem znakowym

To, że jakiś wskaźnik jest na daną typu char, nie oznacza, że to zawsze jest łańcuch znakowy. Może to być wskaźnik na jakiś ciąg bajtów. W tym przypadku ów ciąg zawiera strukturę in_addr i stąd to rzutowanie.

0
0x666 napisał(a):

h_addr_list_[0] - jest łańcuchem znakowym

To, że jakiś wskaźnik jest na daną typu char, nie oznacza, że to zawsze jest łańcuch znakowy. Może to być wskaźnik na jakiś ciąg bajtów. W tym przypadku ów ciąg zawiera strukturę in_addr i stąd to rzutowanie.

Dzięki serdeczne. Mam rozumieć, że rzutowanie odnosi się bezpośrednio do h_addr_list[0]?

1

Tak.

3

Sockety są niestety nieprzyjemnym i mało czytelnym API. Powstały na początku lat 80-tych. Dziś taki design by już raczej nie przeszedł ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0