c++ - sockaddr、sockaddr_in 和 sockaddr_in6 有什么区别?

标签 c++ c api network-programming

我知道 sockaddr_in 用于 IPv4,而 sockaddr_in6 用于 IPv6。让我感到困惑的是 sockaddr 和 sockaddr_in[6] 之间的区别。

有些函数接受sockaddr,有些函数接受sockaddr_insockaddr_in6,所以:

  • 什么是规则?
  • 为什么需要两种不同的结构?

因为 sizeof(sockaddr_in6) > sizeof(sockaddr) == sizeof(sockaddr_in)

  • 这是否意味着如果我们需要支持 ipv4 和 ipv6,我们应该始终使用 sockaddr_in6 在堆栈中分配内存并强制转换为 sockaddr 和 sockaddr_in?

一个例子是:我们有一个socket,我们想得到它的字符串ip地址(可以是ipv4或者ipv6)。

我们先调用getsockname得到一个addr,然后根据addr.sa_family调用inet_ntop

这段代码有什么问题吗?

char ipStr[256];
sockaddr_in6 addr_inv6;
sockaddr* addr = (sockaddr*)&addr_inv6;
sockaddr_in* addr_in = (sockaddr_in*)&addr_inv6;

socklen_t len = sizeof(addr_inv6);
getsockname(_socket, addr, &len);

if (addr->sa_family == AF_INET6) {
    inet_ntop(addr_inv6.sin6_family, &addr_inv6.sin6_addr, ipStr, sizeof(ipStr)); 
    // <<<<<<<<IS THIS LINE VALID, getsockname expected a sockaddr, but we use 
    // it output parameter as sockaddr_in6.
} else {
    inet_ntop(addr_in->sin_family, &addr_in->sin_addr, ipStr, sizeof(ipStr));
}

最佳答案

sockaddr_insockaddr_in6都是第一个成员是 sockaddr 的结构结构。

根据C标准,结构的地址和它的第一个成员是相同的,所以你可以将指针转换为sockaddr_in(6)在指向 sockaddr 的指针中.

函数采用sockaddr_in(6)作为参数可以修改sockaddr部分和函数采用 sockaddr作为参数只关心那部分。

有点像继承。

关于c++ - sockaddr、sockaddr_in 和 sockaddr_in6 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18609397/

相关文章:

c++ - 当代码不严格符合标准时,如何强制 clang 抛出错误?

api - Apollo 服务器多个第三方 API

jquery - 使用 jQuery 从 Wikipedia API 检索 JSON 数据

c# - 使用 C++ 或 C# 与端口通信?

c++ - 如何知道何时创建拷贝?

c - C 中函数调用之前的参数求值顺序

c++ - 如何动态链接 GCC 对象?

c - 打印的值前面有不同数量的空格吗?

ruby-on-rails - 在这种情况下如何避免双重渲染?

c++ - FillRect 在某些情况下不起作用