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 desocklen_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 parsize_t
comme dansread()
,write()
, etc.Tous les types
socklen_t
étaient à l’origine (sous BSD UNIX) de typeint
. Au cours du développement de POSIX.1-2008, il a été décidé de modifier toutes les longueurs de mémoire tampon ensize_t
, ce qui semble logique. Lorsque des systèmessize_t
bits en mode double sont apparus, ce choix a compliqué inutilement les interfaces système, carsize_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
.