socket e glibc

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Rispondi
Avatar utente
Toni
Linux 3.x
Linux 3.x
Messaggi: 999
Iscritto il: lun 30 gen 2006, 22:08
Slackware: slackware-14
Kernel: 3.10.5
Desktop: i3
Località: milano

socket e glibc

Messaggio da Toni »

ciao a tutti
vengo subito al dunque


dal manuale di riferimento delle glibc

Codice: Seleziona tutto

     #include <stdio.h>
     #include <stdlib.h>
     #include <sys/socket.h>
     #include <netinet/in.h>
     #include <netdb.h>
     
     void
     init_sockaddr (struct sockaddr_in *name,
                    const char *hostname,
                    uint16_t port)
     {
       struct hostent *hostinfo;
     
       name->sin_family = AF_INET;
       name->sin_port = htons (port);
       hostinfo = gethostbyname (hostname);
       if (hostinfo == NULL)
         {
           fprintf (stderr, "Unknown host %s.\n", hostname);
           exit (EXIT_FAILURE);
         }
       name->sin_addr = *(struct in_addr *) hostinfo->h_addr;  // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx problema
     }
siamo tutti d'accordo che sin_addr è di tipo struct in_addr infatti:

Codice: Seleziona tutto

— Data Type: struct sockaddr_in

    This is the data type used to represent socket addresses in the Internet namespace. It has the following members:

    sa_family_t sin_family
        This identifies the address family or format of the socket address. You should store the value AF_INET in this member. See Socket Addresses.
    struct in_addr sin_addr         <----------------------------------------------------------------------- 
        This is the Internet address of the host machine. See Host Addresses, and Host Names, for how to get a value to store here.
    unsigned short int sin_port
        This is the port number. See Ports. 
[/code]

Codice: Seleziona tutto


— Data Type: struct in_addr

    This data type is used in certain contexts to contain an IPv4 Internet host address. It has just one field, named s_addr, which records the host address number as an uint32_t. 

ovvero qualcosa del genere

Codice: Seleziona tutto

struct in_addr {
       uint32_t s_addr;
       }  // uint32_t è un intero senza segno (32bit).
h_addr è di tipo char * infatti

Codice: Seleziona tutto

— Data Type: struct hostent

    This data type is used to represent an entry in the hosts database. It has the following members:

    char *h_name
        This is the “official” name of the host.
    char **h_aliases
        These are alternative names for the host, represented as a null-terminated vector of strings.
    int h_addrtype
        This is the host address type; in practice, its value is always either AF_INET or AF_INET6, with the latter being used for IPv6 hosts. In principle other kinds of addresses could be represented in the database as well as Internet addresses; if this were done, you might find a value in this field other than AF_INET or AF_INET6. See Socket Addresses.
    int h_length
        This is the length, in bytes, of each address.
    char **h_addr_list
        This is the vector of addresses for the host. (Recall that the host might be connected to multiple networks and have different addresses on each one.) The vector is terminated by a null pointer.
    char *h_addr         <--------------------  ECCO QUI
     This is a synonym for h_addr_list[0]; in other words, it is the first host address. 
quindi per riempire correttamente il campo s_addr di sin_addr dovrebbe essere cosi o sbaglio ?
(name->sin_addr).s_addr = *(struct in_addr *) hostinfo->h_addr;

poi non capisco
h_addr è un vettore di 4 char ovvero 32bit (giusto per contenere un indirizzo ip a 32 bit (ipv4))

è possibile che tramite il cast tutto il contenuto del vettore h_addr sia copiato in s_addr ?????

ciao a grazie

Avatar utente
ildiama
Linux 3.x
Linux 3.x
Messaggi: 536
Iscritto il: mar 27 dic 2005, 16:49
Slackware: mine
Kernel: 2.6.alto..
Desktop: KDE4
Località: Senigallia
Contatta:

Re: socket e glibc

Messaggio da ildiama »

name->sin_addr è di tipo struct in_addr come hostent::h_addr dopo il cast. Qunidi, perché complicarsi la vita? Forse ti confonde il fatto che la struttura contiene solo un campo. Se vuoi fare come dici tu (ma è inutile, ripeto) devi fare un cast differente.

La risposta alla seconda domanda è sì, è possibile. Potenza del C..

Rispondi