gpt4 book ai didi

C 套接字双栈 ss_family 始终 IPv6

转载 作者:行者123 更新时间:2023-12-03 12:02:59 36 4
gpt4 key购买 nike

使用 accept() 时或 getpeername() , sockaddr_storage总是有 ss_family=AF_INET6 :

struct sockaddr_storage address = {0};
socklen_t sockaddrlen = sizeof(address);
int client = accept(sock, (struct sockaddr*)(&address), &sockaddrlen);
if (client < 0) {
perror("Unable to accept");
exit(EXIT_FAILURE);
}
if( address.ss_family==AF_INET6 ){
std::cout << "IPv6" << std::endl;
} else {
std::cout << "IPv4" << std::endl;
}

我觉得它与创作有关:

s = socket(AF_INET6, SOCK_STREAM, 0);

或绑定(bind)

struct sockaddr_in6 addr;
memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(port);
addr.sin6_addr = in6addr_any;

if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) {

我怎样才能得到 ss_family更正,或以另一种方式告诉它是什么样的IP?

最佳答案

双栈套接字是 IPv6 套接字,仅支持 IPv4,因此其 IP 地址将始终为 AF_INET6地址。但是,对于 IPv4 连接,这些地址将是 IPv4-mapped IPv6 addresses .

Hybrid dual-stack IPv6/IPv4 implementations recognize a special class of addresses, the IPv4-mapped IPv6 addresses. These addresses are typically written with a 96-bit prefix in the standard IPv6 format, and the remaining 32 bits written in the customary dot-decimal notation of IPv4.

Addresses in this group consist of an 80-bit prefix of zeros, the next 16 bits are ones, and the remaining, least-significant 32 bits contain the IPv4 address. For example, ::ffff:192.0.2.128 represents the IPv4 address 192.0.2.128. Another format, called "IPv4-compatible IPv6 address", is ::192.0.2.128; however, this method is deprecated.



您需要明确检测到,请参阅 How to resolve IPv4 address from IPv4 mapped IPv6 address? , 例如 :

#ifndef IN6_IS_ADDR_V4MAPPED
#define IN6_IS_ADDR_V4MAPPED(a) \
((((a)->s6_words[0]) == 0) && \
(((a)->s6_words[1]) == 0) && \
(((a)->s6_word[2]) == 0) && \
(((a)->s6_word[3]) == 0) && \
(((a)->s6_word[4]) == 0) && \
(((a)->s6_word[5]) == 0xFFFF))
#endif

struct sockaddr_storage address = {0};
socklen_t sockaddrlen = sizeof(address);
int client = accept(sock, (struct sockaddr*)(&address), &sockaddrlen);
if (client < 0) {
perror("Unable to accept");
exit(EXIT_FAILURE);
}
if (address.ss_family == AF_INET6){
struct sockaddr_in6 *addr = (struct sockaddr_in6*)(&address);
if (IN6_IS_ADDR_V4MAPPED(&(addr->sin6_addr))) {
std::cout << "IPv4 (mapped)" << std::endl;
} else {
std::cout << "IPv6" << std::endl;
}
} else {
std::cout << "IPv4" << std::endl;
}

关于C 套接字双栈 ss_family 始终 IPv6,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59505846/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com