Estoy portar una aplicaciónIPv4 a una base de código AF-independiente (que debería funcionar con IPv4 e IPv6). Ahora estoy usando sockaddr_storage donde puedo, sin embargo ahora tengo que configurar (poblar) un sockaddr_storage. Pero no sé cuál es la forma correcta. El código anterior era:Definición de la dirección IPv4/IPv6 y el puerto a una estructura sockaddr_storage
// defined in data_socket.h
struct sockaddr_in laddr;
Ahora hay esta función que establece sin_addr y sin_port:
void DataSocket::SetLocalAddr(const char *addr, const int port)
{
this->laddr.sin_port = htons(port);
if(addr != NULL)
this->laddr.sin_addr.s_addr = inet_addr(addr);
else
this->laddr.sin_addr.s_addr = inet_addr("0.0.0.0");
}
Como se ve es el viejo estilo (utiliza IPv4).
Ahora mis cambios están por debajo. En primer lugar he cambiado sockaddr_in
a sockaddr_storage
// defined in data_socket.h
struct sockaddr_storage laddr;
Luego cambié el código anterior para apoyar IPv4 y IPv6:
void DataSocket::SetLocalAddr(const char *addr, const int port)
{
switch (this->GetAddrFamily(addr)) {
case AF_INET:
(struct sockaddr_in *) this->laddr.sin_port = htons(port);
if(addr != NULL)
inet_pton(AF_INET, addr, (struct sockaddr_in *) this->laddr.sin_addr);
else
inet_pton(AF_INET, "0.0.0.0", (struct sockaddr_in *) this->laddr.sin_addr);
break;
case AF_INET6:
(struct sockaddr_in6 *) this->laddr.sin6_port = htons(port);
if(addr != NULL)
inet_pton(AF_INET6, addr, (struct sockaddr_in6 *) this->laddr.sin6_addr);
else
inet_pton(AF_INET6, "0:0:0:0:0:0:0:0", (struct sockaddr_in6 *) this->laddr.sin6_addr);
break;
default:
return NULL;
}
}
Donde es GetAddrFamily()
:
int DataSocket::GetAddrFamily(const char *addr)
{
struct addrinfo hints, *res;
int status, result;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((status = getaddrinfo(addr, 0, &hints, &res)) != 0)
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
return false;
}
result = res->ai_family; // This might be AF_INET, AF_INET6,etc..
freeaddrinfo(res); // We're done with res, free it up
return result;
}
Parece que mi camino es complejo. ¿Es esta la forma correcta de hacer esto? Debido a que he cambiado sockaddr_in a sockaddr_storage, en realidad sólo quiero el reverso de esta pregunta: Getting IPV4 address from a sockaddr structure
Estoy tratando de encontrar la mejor solución, por ejemplo aquí: http://www.kame.net/newsletter/19980604/ nunca dice que el uso inet_ntop()
y inet_pton()
, sin embargo algunos otros (como el tutorial de red de Beej) dice que inet_ntop()
y inet_pton()
se deben usar para la aplicación basada en IPv6.
¿Mi forma de implementación es correcta o debería cambiarla?
Esta es una razón por la que me gusta 'boost :: asio :: ip :: address', abstrae' boost :: asio :: ip :: address_v4' y 'boost :: asio :: ip :: address_v6'. – Chad
Avíseme cuando C obtenga funciones de miembro. – Puppy
@DeadMG uy disculpe por la etiqueta 'c' –