Обнуляйте структуру sockaddr_in
| | |
Хотя обычно используется только три поля из структуры sockaddr_in: sin_family, sin_port и sin_addr, но, как правило, в ней есть и другие поля. Например, во многих реализациях есть поле sin_len, содержащее длину структуры. В частности, оно присутствует в системах, производных от версии 4.3BSD Reno и более поздних. Напротив, в спецификации Winsock этого поля нет.
Если сравнить структуры sockaddr_in в системе FreeBSD
struct sockaddr_in {
u_char sin_len;
u_char sin_family;
u_char sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
и в Windows
struct sockaddr_in {
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
}
то видно, что в обеих структурах есть дополнительное поле sin_zero. Хотя это поле и не используется (оно нужно для того, чтобы длина структуры sockaddr_in была равна в точности 16 байт), но тем не менее должно быть заполнено нулями.
Примечание: Причина в том, что в некоторых реализациях во время привязки адреса к сокету производится двоичное сравнение этой адресной структуры с адресами каждого интерфейса.Такой код будет работать только в том случае, если поле sin_zero заполнено нулями.
Поскольку в любом случае необходимо обнулить поле sin_zero, обычно перед использованием адресной структуры ее полностью обнуляют. В этом случае заодно очищаются и все дополнительные поля, так что не будет проблем из-за недокументированных полей. Посмотрите на листинг 2.3 - сначала в функции set_address Делается вызов bzero для очистки структуры sockaddrjn.
| | |