getnameinfo spécifie socklen_t

Le 2ème argument du prototype getnameinfo demande un type socklen_t mais sizeof utilise size_t. Alors, comment puis-je obtenir socklen_t?

Prototype:

int getnameinfo(const struct sockaddr *ressortingct sa, socklen_t salen, char *ressortingct node, socklen_t nodelen, char *ressortingct service, socklen_t servicelen, int flags); 

Exemple:

 struct sockaddr_in SIN; memset(&SIN, 0, sizeof(SIN)); // This should also be socklen_t ? SIN.sin_family = AF_INET; SIN.sin_addr.s_addr = inet_addr(IP); SIN.sin_port = 0; getnameinfo((struct sockaddr *)&SIN, sizeof(SIN) /* socklen_t */, BUFFER, NI_MAXHOST, NULL, 0, 0); 

Cela donnera une erreur du compilateur:

 socklen_t VAR; getnameinfo((struct sockaddr *)&SIN, &VAR, BUFFER, NI_MAXHOST, NULL, 0, 0); 

size_t est défini en tant que type intégral non signé; C99 garantit qu’il est au moins 16 bits.

socklen_t est défini comme un type intégral d’au moins 32 bits. ( Edit: ce n’est pas nécessairement non signé, bien qu’en pratique une longueur négative ne veuille rien dire.)

Il n’y a donc aucun problème à passer un paramètre size_t et à laisser le compilateur le socklen_t implicitement en socklen_t , et je dirais que cela rend le code plus clair pour laisser la conversion implicite se produire au lieu d’append des conversions pédantiques.

Votre dernier exemple

 socklen_t VAR; getnameinfo((struct sockaddr *)&SIN, &VAR, BUFFER, NI_MAXHOST, NULL, 0, 0); 

donne une erreur de compilation parce que vous passez un pointeur sur socken_t au lieu d’un socklen_t.

Vos informations sont obsolètes, socklen_t est un type entier (pas nécessairement non signé) d’au moins 32 bits ( http://www.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html ).

(C’est plutôt une réponse à cette question à socklen_t , faussement dupliquée, qui tente de faire la socklen_t sur l’existence de socklen_t .)

Comme d’autres l’ont souligné, cela peut être considéré comme l’équivalent size_t de l’API POSIX Sockets, qui représente la longueur en octets de diverses structures de données. C’est le plus notable dans les fonctions bind() , listen() , connect() où il indique la longueur des différentes implémentations de struct sockaddr mais il n’y est pas limité du tout.

La spécification POSIX explique réellement comment il est devenu et est très instructive à mon humble avis:

Le type socklen_t été inventé pour couvrir la gamme d’implémentations vues sur le terrain. Le but de socklen_t est d’être le type de toutes les longueurs naturellement délimitées en taille; c’est-à-dire qu’ils sont la longueur d’un tampon qui ne peut pas raisonnablement devenir de taille énorme: adresses réseau, noms d’hôte, représentations de chaînes de ceux-ci, données auxiliaires, messages de contrôle et options de socket sont des exemples. Les tailles véritablement illimitées sont représentées par size_t comme dans read() , write() , etc.

Tous les types socklen_t étaient à l’origine (sous BSD UNIX) de type int . Au cours du développement de POSIX.1-2008, il a été décidé de modifier toutes les longueurs de mémoire tampon en size_t , ce qui semble logique. Lorsque des systèmes size_t bits en mode double sont apparus, ce choix a compliqué inutilement les interfaces système, car size_t (avec long) était d’une taille différente sous les modèles ILP32 et LP64. Il aurait été possible de revenir à int , sauf que certaines implémentations avaient déjà livré des interfaces 64 bits uniquement. Le compromis était un type qui pouvait être défini comme n’importe quelle taille par l’implémentation: socklen_t .