2017-01-24 2 views
0

В настоящее время я пишу библиотеку C, в которой используются сетевые структуры, такие как sockaddr. В моем коде я использую это тернарное условие, чтобы вывести размер такой структуры.struct sockaddr, нам действительно нужно дать addrlen

addrlen = sourceaddr->sa_family == 
      AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); 

Однако, большинство стандартных функций UNIX, такие как bind имеет такую ​​подпись:

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 

Он содержит четкое указание длины адреса addrlen.

Мой вопрос: «Зачем мне нужно явное указание адреса len в моей библиотеке, если я могу вывести его с помощью sa_family

Например, вызов привязки может изменить к этой подписи:

int bind(int sockfd, const struct sockaddr *addr); 

И использовать внутренне:

__bind(sockfd, addr, 
     addr->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)); 

Большое спасибо

+0

Обратная совместимость. И если вы измените подпись своей функции 'bind', то вы перестанете соответствовать требованиям POSIX (если вы этого хотите) или совместимы с любой другой функцией' bind'. –

+0

Хорошо. Это означает, что в предыдущей структуре sockaddr не было поля sa_family? Итак, что бы вы посоветовали для недавней библиотеки: используйте или не addrlen? Спасибо :) –

ответ

0

Это связано с розеткой историю API между различных операционных систем. Каждая система имела свою собственную реализацию сокетов, и такой API не был стандартизирован среди них.

socklen_t странное ЬурейеЕ для размера STRUCT SOCKADDR в принимают(), getpeername(), и подключить().

Причиной этого ЬурейеЕ является то, что в BSD, эти функции взял Int *, и POSIX люди ввинчивается все это, когда они решили сделать такие аргументы указывают на целое число (потенциально) другого размера, под новым typedef.

Смежные вопросы