问题描述
限时送ChatGPT账号..我知道 sockaddr_in 用于 IPv4,而 sockaddr_in6 用于 IPv6.令我困惑的是 sockaddr 和 sockaddr_in[6] 之间的区别.
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].
有些函数接受sockaddr
,有些函数接受sockaddr_in
或sockaddr_in6
,所以:
Some functions accept sockaddr
and some functions accept sockaddr_in
or sockaddr_in6
, so:
并且因为 sizeof(sockaddr_in6) >sizeof(sockaddr) == sizeof(sockaddr_in)
.
一个例子是:我们有一个socket,我们想得到它的字符串ip地址(可以是ipv4或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).
我们首先调用getsockname
获取addr
,然后根据addr.sa_family
调用inet_ntop
.
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?
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));
}
推荐答案
我不想回答我的问题.但是为了在这里提供更多对其他人有用的信息,我决定回答我的问题.
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.
深入linux
的源代码后.以下是我的发现,可能有多种协议都实现了 getsockname
.并且每个都有自己的底层地址数据结构,例如,对于IPv4,它是sockaddr_in
,而对于AF_UNIX,IPV6是
sockaddr_in6
,而sockaddr_un
套接字.sockaddr
在这些 API 的签名中用作公共数据支柱.
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.
那些 API 将根据 memcpy 的另一个参数 length
将 socketaddr_in 或 sockaddr_in6 或 sockaddr_un 复制到 sockaddr.
Those API will copy the socketaddr_in or sockaddr_in6 or sockaddr_un to sockaddr base on another parameter length
by memcpy.
并且所有数据结构都以相同类型的字段 sa_family 开头.
And all of the data structure begin with same type field sa_family.
基于这些原因,代码片段是有效的,因为 sockaddr_in
和 sockaddr_in6
都有 sa_family
然后我们可以将它转换为检查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,我不知道为什么 sizeof(sockaddr_in6) >sizeof(sockaddr)
,这导致基于 sockaddr 的大小分配内存对于 ipv6 来说是不够的(容易出错),但我想这是因为历史原因.
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、sockaddr_in 和 sockaddr_in6 有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
更多推荐
[db:关键词]
发布评论