getnameinfo указывает socklen_t - PullRequest
3 голосов
/ 04 мая 2010

2-й аргумент для прототипа getnameinfo запрашивает тип socklen_t, но sizeof использует size_t. Так как я могу получить socklen_t?

Прототип:

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

Пример:

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);

Это даст ошибку компилятора:

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

Ответы [ 3 ]

9 голосов
/ 04 мая 2010

size_t определяется как как беззнаковый целочисленный тип; C99 гарантирует, что это по крайней мере 16 бит.

socklen_t определяется как как целочисленный тип длиной не менее 32 бит. ( Редактировать: Это не обязательно без знака, хотя на практике отрицательная длина была бы бессмысленной.)

Так что нет проблем с передачей параметра size_t и разрешением компилятору неявно приводить его к socklen_t, и я бы сказал, что он делает ваш код более понятным, чтобы неявное преобразование происходило вместо добавления педантичных приведений. *

Ваш последний пример

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

выдает ошибку компилятора, потому что вы передаете указатель на socken_t вместо socklen_t.

1 голос
/ 04 мая 2010

Ваша информация устарела, socklen_t является целочисленным типом (не обязательно без знака), по крайней мере, 32 бит (http://www.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html).

0 голосов
/ 13 декабря 2017

(Это скорее ответ на этот ИМХО ложно помеченный тегом вопрос , который пытается докопаться до сути socklen_t.)

Как отмечали другиеего можно рассматривать как size_t эквивалент POSIX Sockets API, который представляет длину различных структур данных в байтах.Это наиболее заметно в функциях bind(), listen(), connect(), где оно обозначает длину различных реализаций struct sockaddr, но не ограничивается этим вообще.

Спецификация POSIX фактически объясняет, как это стало, и очень поучительна. ИМХО:

Тип socklen_t был изобретен для охвата диапазона реализаций, видимых в полевых условиях.Цель socklen_t - быть типом для всех длин, которые естественно ограничены в размере;это означает, что они имеют длину буфера, который не может разумно стать огромным: сетевые адреса, имена хостов, их строковые представления, вспомогательные данные, управляющие сообщения и параметры сокетов являются примерами.Действительно безграничные размеры представлены size_t, как в read(), write() и т. Д.

Все типы socklen_t были изначально (в BSD UNIX) типа int.Во время разработки POSIX.1-2008 было решено изменить все длины буфера на size_t, что имеет смысл по номиналу.Когда появились двухрежимные 32/64-битные системы, этот выбор излишне усложнил системные интерфейсы, потому что size_t (с длинным) был другого размера в моделях ILP32 и LP64.Возврат к int произошел бы за исключением того, что некоторые реализации уже поставляли только 64-битные интерфейсы.Компромисс был типом, который может быть определен как любой размер реализацией: socklen_t.

...