Я пишу небольшую программу сокетов, которая привязана только к указанному ip: port, но bind() не удалось, если struct sockaddr_in не является bzero и gcc с опцией -O2.Socket bind failed на sockaddr_in без bzero
Вот коды:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
int main(int argc, char **argv){
struct sockaddr_in addr;
//bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons((unsigned short)9009);
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
int sock;
if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("socket error");
exit(0);
}
if(bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1){
printf("socket error: %d, %s\n", errno, strerror(errno));
exit(0);
}
return 0;
}
Обратите внимание bzero(&addr, sizeof(addr));
закомментирован, я намерен парафировать sockadd_in каждого члена. Компиляция и запуск:
$ gcc a.c; ./a.out
OK
$ gcc -O2 a.c; ./a.out
socket error: 49, Can't assign requested address
Мы знаем, что структура sockadd_in определяется как:
struct in_addr {
in_addr_t s_addr; /* 32-bit IPv4 address */
/* network byte ordered */
};
struct sockaddr_in {
uint8_t sin_len; /* length of structure (16) */
sa_family_t sin_family; /* AF_INET */
in_port_t sin_port; /* 16-bit TCP or UDP port number */
/* network byte ordered */
struct in_addr sin_addr; /* 32-bit IPv4 address */
/* network byte ordered */
char sin_zero[8]; /* unused */
};
Мой вопрос, имеет ли привязка() реализация зависит от sockaddr_in.sin_zero очищаются?
Edit: Mac OS X, Darwin Kernel Version 12.4.0 X86_64
Я бы рекомендовал распечатать значение errno, когда сбой не выполняется. Это должно сказать нам немного больше об отказе. –
Я не могу воспроизвести вашу проблему (запущенная программа в цикле несколько тысяч раз). Однако структура очистки является хорошей практикой, особенно когда вы уже столкнулись с ошибкой один раз. – keltar
Вы не устанавливаете поле «sin_len». Я бы это исправил и повторил. – EJP