Tôi porting một ứng dụng IPv4 sang một codebase AF-độc lập (nó nên làm việc với IPv4 và IPv6). Bây giờ tôi đang sử dụng sockaddr_storage bất cứ nơi nào tôi có thể, tuy nhiên bây giờ tôi phải đặt (điền) một số sockaddr_storage. Nhưng tôi không biết cách chính xác là gì. Mã trước đây là:Thiết địa chỉ IPv4/IPv6 và cổng vào một cấu trúc sockaddr_storage
// defined in data_socket.h
struct sockaddr_in laddr;
Bây giờ có chức năng này mà bộ sin_addr và 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");
}
Như bạn thấy đây là phong cách cũ (sử dụng IPv4).
Bây giờ, các thay đổi của tôi ở bên dưới. Trước tiên tôi đã thay đổi sockaddr_in
để sockaddr_storage
// defined in data_socket.h
struct sockaddr_storage laddr;
Sau đó, tôi đã thay đổi mã trên để hỗ trợ IPv4 và 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;
}
}
đâu GetAddrFamily()
là :
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;
}
Dường như cách của tôi phức tạp. Đây có phải là cách đúng để thực hiện việc này không? Bởi vì tôi đã thay đổi sockaddr_in để sockaddr_storage, thực sự tôi chỉ muốn điều ngược lại của câu hỏi này: Getting IPV4 address from a sockaddr structure
Tôi đang cố gắng tìm ra giải pháp tốt nhất, ví dụ ở đây: http://www.kame.net/newsletter/19980604/ nó nói bao giờ sử dụng inet_ntop()
và inet_pton()
, tuy nhiên một số người khác (như hướng dẫn mạng của Beej) nói rằng inet_ntop()
và inet_pton()
nên được sử dụng cho IPv6 ứng dụng dựa trên.
Cách triển khai của tôi có đúng không hoặc tôi có nên thay đổi không?
Đây là một lý do tại sao tôi thích 'boost :: asio :: ip :: address', nó tóm tắt đi' boost :: asio :: ip :: address_v4' và 'boost :: asio :: ip :: address_v6'. – Chad
Hãy cho tôi biết khi nào C có chức năng thành viên. – Puppy
@DeadMG oops xin lỗi vì thẻ 'c' –