为什么在调用 bind() 时要将 sockaddr_in 转换为 sockaddr?

2024-10-21 09:14:00
admin
原创
329
摘要:问题描述:bind ()函数接受指向 的指针sockaddr,但在我见过的所有例子中,sockaddr_in都使用结构来代替,并转换为sockaddr:struct sockaddr_in name; ...; if (bind (sock, (struct sockaddr *) &name...

问题描述:

bind ()函数接受指向 的指针sockaddr,但在我见过的所有例子中,sockaddr_in都使用结构来代替,并转换为sockaddr

struct sockaddr_in name;
...;
if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
  ...;
}

我不明白为什么要sockaddr_in使用结构体。为什么不直接准备并传递一个sockaddr

这只是惯例吗?


解决方案 1:

不,这不仅仅是惯例。

sockaddr是任何类型的套接字操作的通用描述符,而是sockaddr_in基于 IP 通信的特定结构(如果我没记错的话,“in”代表“InterNet”)。据我所知,这是一种“多态性”:该bind()函数假装接受一个struct sockaddr *,但实际上,它会假定传入了适当类型的结构;即与您作为第一个参数提供的套接字类型相对应的结构。

解决方案 2:

我不知道这是否与这个问题非常相关,但我想提供一些额外的信息,这可能会使类型种姓更容易理解,因为许多没有花太多时间的人C看到这样的类型种姓会感到困惑。

我使用macOS,因此我根据系统中的头文件来举例。

struct sockaddr定义如下:

struct sockaddr {
    __uint8_t       sa_len;         /* total length */
    sa_family_t     sa_family;      /* [XSI] address family */
    char            sa_data[14];    /* [XSI] addr value (actually larger) */
};

struct sockaddr_in定义如下:

struct sockaddr_in {
    __uint8_t       sin_len;
    sa_family_t     sin_family;
    in_port_t       sin_port;
    struct  in_addr sin_addr;
    char            sin_zero[8];
};

从最基础的开始,指针只包含一个地址。所以struct sockaddr *struct sockaddr_in *几乎相同。它们都只存储一个地址。唯一相关的区别是编译器如何处理它们的对象。

因此,当您说时(struct sockaddr *) &name,您只是在欺骗编译器并告诉它这个地址指向一个struct sockaddr类型。


假设指针指向某个位置1000。如果struct sockaddr *存储了该地址,它将根据结构定义考虑从1000到的内存拥有成员。如果存储了相同的地址,它将考虑从到 的内存。sizeof(struct sockaddr)`struct sockaddr_in *1000sizeof(struct sockaddr_in)`


当您对该指针进行类型转换时,它将考虑相同的字节序列sizeof(struct sockaddr)

struct sockaddr *a = &name; // consider &name = 1000

现在,如果我访问a->sa_len,编译器将从 位置访问1000sizeof(__uint8_t)其字节大小与 的情况相同sockaddr_in。因此这应该访问相同的字节序列。

同样的模式也适用于sa_family

之后有一个 14 字节字符数组,其中struct sockaddr存储来自in_port_t sin_porttypedef16 位无符号整数 = 2 字节)、struct in_addr sin_addr(简单来说 32 位 ipv4 地址 = 4 字节)和char sin_zero[8](8 字节)的数据。这 3 个加起来是 14 个字节。

现在这三个都存储在这个 14 字节字符数组中,我们可以通过访问适当的索引并再次对其进行类型转换来访问这三个中的任何一个。

user529758 的回答已经解释了这样做的原因。

解决方案 3:

这是因为 bind 可以绑定除 IP 套接字之外的其他类型的套接字,例如 Unix 域套接字,其类型为 sockaddr_un。AF_INET 套接字的地址包含主机和端口,而 AF_UNIX 套接字包含文件系统路径。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用