类型转换sockaddr结构体

3
我正在尝试学习网络编程和C语言。我对两个结构体sockaddr(通用地址)和sockaddr_in感到困惑。我的书上这样说:
因此,我们可以填充一个sockaddr_in的字段,然后将其(指针)转换为(指向)sockaddr的指针,并将其传递给socket函数,该函数查看sa_family字段以了解实际类型,然后再次转换为适当的类型。
但是在我看来,这两个结构体似乎不应该兼容?其中一个有两个字段,
struct sockaddr {
    sa_family_t sa_family;
    char sa_data[14];
};

另一个有很多。
struct in_addr {
    uint32_t s_addr;
};

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

它们在内存中都有16个字节大小。我猜这就是为什么要在sockaddr_in结构中补零,以便进行转换?我仍然感到困惑-如果您不立即转换回来,那么转换是否有意义?它总是一个临时转换吗,利用sa_family_t字段位于前N位的事实吗?


关于网络相关的所有事情,请参阅Beej's Guide to Network Programming。这是一个非常好的网络编程参考/教程,它几乎**100%**适用于您当前的问题。 - David C. Rankin
1个回答

1

您不需要转换 struct,而是需要其指针。

与之相关的调用信息,即引用的是哪个 struct,可以从 sin_family 成员中获取,该成员在任何情况下都可用。

因此,本质上转换只是为了消除编译器的警告,因为被调用的函数期望一个指向 struct sockaddr 的指针,但实际上传递了一个指向不同类型的指针。


"让编译器保持安静" 这不是未定义行为吗? - usr
只有当结果指针未正确对齐时,才会调用未定义的行为。C11草案6.3.2.3/7:“可以将指向对象类型的指针转换为指向不同对象类型的指针。如果引用类型的指针未正确对齐,则行为未定义。 - alk
好的,创建指针可能是允许的,但据我所知解除引用是不允许的。 - usr
如果对齐正确,从转换结果得到的指针很可能会被取消引用。如果这是不允许/不可能的,整个套接字接口将被破坏。 - alk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接