getaddrinfo()
может возвращать несколько записей, в том числе IPv6.И это может быть вашей проблемой.
Обратите внимание, что после вызова getaddrinfo()
проверка ошибок отсутствует.
Если вы хотите, чтобы браузер смог подключиться к "127.0.0.1:PORT", выследует либо:
bind()
на INADDR_LOOPBACK и ПОРТ без какой-либо помощи из getaddrinfo()
- , правильно настроить вызов на
getaddrinfo()
, установить ai_family
на AF_INET
(так что у вас есть только IPv4).
Обратите внимание, что если первый параметр getaddrinfo()
равен NULL, то возвращаемый адрес будет установлен в INADDR_ANY / IN6ADDR_ANY, что означает, что ваш сервер также будет приниматьсоединения снаружи.Чтобы ограничить соединения локальным хостом, установите для первого параметра значение «localhost» вместо NULL.
Чтобы увековечить кусок, вот мой код дампера результата getaddrinfo()
:
struct addrinfo hints, *aires=0, *ai;
int i;
int rc;
memset( &hints, 0, sizeof(hints) );
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
rc = getaddrinfo( "localhost", "1500", &hints, &aires );
if (rc == 0) {
for ( ai=aires, i=0; ai; ai=ai->ai_next, i++ ) {
printf( "gai: ai[%d].ai_canonname = %s\n", i, ai->ai_canonname );
printf( "gai: ai[%d].ai_flags = %d\n", i, ai->ai_flags );
printf( "gai: ai[%d].ai_family = %d (%s)\n", i, ai->ai_family, get_family_name(ai->ai_family) );
printf( "gai: ai[%d].ai_socktype = %d\n", i, ai->ai_socktype );
printf( "gai: ai[%d].ai_protocol = %d (%s)\n", i, ai->ai_protocol, get_proto_name(ai->ai_protocol) );
printf( "gai: ai[%d].ai_addrlen = %d\n", i, (int)ai->ai_addrlen );
if (ai->ai_family == AF_INET) {
struct sockaddr_in *sa = (struct sockaddr_in *)ai->ai_addr;
printf( "gai: ai[%d].ai_addr[IPv4].sin_family = %d (%s)\n", i, sa->sin_family, get_family_name(sa->sin_family) );
printf( "gai: ai[%d].ai_addr[IPv4].sin_port = %d\n", i, ntohs(sa->sin_port) );
printf( "gai: ai[%d].ai_addr[IPv4].sin_addr = %s\n",
i, inet_ntop(AF_INET, &sa->sin_addr, buf, sizeof(buf)) );
} else if (ai->ai_family == AF_INET6) {
struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ai->ai_addr;
printf( "gai: ai[%d].ai_addr[IPv6].sin6_family = %d (%s)\n", i, sa->sin6_family, get_family_name(sa->sin6_family) );
printf( "gai: ai[%d].ai_addr[IPv6].sin6_port = %d\n", i, ntohs(sa->sin6_port) );
printf( "gai: ai[%d].ai_addr[IPv6].sin6_flowinfo = %d\n", i, sa->sin6_flowinfo );
printf( "gai: ai[%d].ai_addr[IPv6].sin6_addr = %s\n",
i, inet_ntop(AF_INET6, &sa->sin6_addr, buf, sizeof(buf)) );
printf( "gai: ai[%d].ai_addr[IPv6].sin6_scope_id = %d\n", i, sa->sin6_scope_id );
} else {
printf( "gai: ai[%d].ai_addr = %p\n", i, ai->ai_addr );
}
printf("\n");
}
} else {
printf( "gai: failed (%d)\n", rc );
}
freeaddrinfo( aires );