什么是套接字地址SOCKADDR_IN和sockaddr_in6的区别? [英] What's the difference between sockaddr, sockaddr_in, and sockaddr_in6?

查看:1805
本文介绍了什么是套接字地址SOCKADDR_IN和sockaddr_in6的区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道SOCKADDR_IN是对于IPv4,并为sockaddr_in6的IPv6的。这种混乱对我来说是SOCKADDR和SOCKADDR_IN之间的差异[6]。

某些函数接受的sockaddr 和一些函数接受 SOCKADDR_IN 体sockaddr_in6 ,所以:


  • 有什么规则?

  • 为什么有需要两种不同的结构?

和因为的sizeof(体sockaddr_in6)GT;的sizeof(SOCKADDR)==的sizeof(SOCKADDR_IN)


  • 这是否意味着我们应该经常使用到sockaddr_in6的堆栈中分配内存和强制转换为sockaddr并有sockaddr_in如果我们需要支持IPv4和IPv6?

一个例子是:我们有一个插座上,我们希望得到它的字符串的IP地址(可以是IPv4或IPv6)

我们第一次调用 getsockname 来获得地址,然后调用 inet_ntop 根据 addr.sa_family

这有什么不对的code段?

 体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,地址,和放大器; LEN);
焦炭ipStr [256];
如果(addr->上sa_family == AF_INET6)
{
    inet_ntop(addr_inv6.sin6_family,&安培; addr_inv6.sin6_addr,ipStr,sizeof的(ipStr));
    //<<<<<<<<这是线路有效,getsockname预期sockaddr的,但我们把它输出参数为体sockaddr_in6。
}
其他
{
    inet_ntop(addr_in-> sin_family,&安培; addr_in-> sin_addr,属于ipStr,sizeof的(ipStr));
}


解决方案

我不想回答我的问题。但是,给这里的更多信息,我决定回答我的问题可能是别人有用的。

钻进去的Linux源$ C ​​$ C后。以下是我的发现,还有一些都实现了 getsockname 可能的多个协议。而且每个人都有自理下属地址数据结构,例如,对于IPv4是 SOCKADDR_IN 和IPV6 体sockaddr_in6 sockaddr_un AF_UNIX 插座。 的sockaddr 被用作这些API的签名常见的数据支撑。

这些API将复制socketaddr_in或或sockaddr_in6的到sockaddr_un另一个参数长度则memcpy指向sockaddr基地。

和所有的数据结构的开始与上sa_family相同类型字段

基础对​​原因,code段是有效的,因为这两个 SOCKADDR_IN 体sockaddr_in6 上sa_family 然后我们就可以检查后,将它转换为正确的数据结构使用上sa_family

BTY,我不知道为什么的sizeof(体sockaddr_in6)GT;的sizeof(SOCKADDR),它造成的sockaddr的大小分配内存的基础是不够的,IPv6的(即容易出错),但我想这是因为历史原因。

I know that sockaddr_in is for IPv4, and sockaddr_in6 for IPv6. The confusion to me is the difference between sockaddr and sockaddr_in[6].

Some functions accept sockaddr and some functions accept sockaddr_in or sockaddr_in6, so:

  • what's the rule?
  • And why is there a need for two different structures?

And because the sizeof(sockaddr_in6) > sizeof(sockaddr) == sizeof(sockaddr_in).

  • Does that mean we should always use sockaddr_in6 to allocate memory in stack and cast to sockaddr and sockaddr_in if we need to support ipv4 and ipv6?

One example is: we have a socket, and we want to get the string ip address of it (it can be ipv4 or ipv6).

We first call getsockname to get an addr and then call inet_ntop based on the addr.sa_family.

Is there anything wrong with this code snippet?

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);
char ipStr[256];
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));
}

解决方案

I don't want to answer my question. But to give more information here which might be useful to other people, I decide to answer my question.

After dig into the source code of linux. Following is my finding, there are possible multiple protocol which all implement the getsockname. And each have themself underling address data structure, for example, for IPv4 it is sockaddr_in, and IPV6 sockaddr_in6, and sockaddr_un for AF_UNIX socket. sockaddr are used as the common data strut in the signature of those APIs.

Those API will copy the socketaddr_in or sockaddr_in6 or sockaddr_un to sockaddr base on another parameter length by memcpy.

And all of the data structure begin with same type field sa_family.

Base on those reason, the code snippet is valid, because both sockaddr_in and sockaddr_in6 have sa_family and then we can cast it to the correct data structure for usage after check sa_family.

BTY, I'm not sure why the sizeof(sockaddr_in6) > sizeof(sockaddr), which cause allocate memory base on size of sockaddr is not enough for ipv6( that is error-prone), but I guess it is because of history reason.

这篇关于什么是套接字地址SOCKADDR_IN和sockaddr_in6的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆