在sockaddr和sockaddr_in之间进行转换

anu*_*g86 4 c++ network-programming

我遇到了一个套接字编程教程,其中引用了它

“指向结构sockaddr_in的指针可以转换为指向结构sockaddr的指针,反之亦然

我不明白如何将sockaddr_in强制转换为sockaddr。将Big类型的指针转换为Small类型的指针应具有UD行为。

struct sockaddr {
unsigned short sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address
};


struct sockaddr_in {
short int sin_family; // Address family, AF_INET
unsigned short int sin_port; // Port number
struct in_addr sin_addr; // Internet address
unsigned char sin_zero[8]; // Same size as struct sockaddr
};
Run Code Online (Sandbox Code Playgroud)

如何不能强制转换?将它们相互投射是不安全的吗?

如果我有一个A类只有两个整数,而B类则只有4个整数。如果我有一个类型为B的指针并将其强制转换为类型A,那么请确保我可以获取前两个元素。但是,如果类A具有首先声明的2个字符和之后声明的2个整数,则指针将无法正确获取值,因为在这种情况下,对象布局将有所不同。

编辑1:

class Anu
{
public:
    char a;
    int b;
    Anu()
    {
        a='a';
    }
};
class Anurag
{
public:
    Anurag() { a=4;}
    int a;
    int b;
    int c;
    int d;
};
int main()
{
        Anu objanu;
        Anurag objanurag;
        Anurag *ptrAnurag= &objanurag;
        ptrAnurag= (Anurag*)&objanu;
        cout<<ptrAnurag->a; //Some weird value here
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

假设我更改示例,以便通过调整变量类型使两个类具有相同的大小...即使大小保持不变,对象布局仍可能不同。

Dav*_*aim 5

我将在@gsamaras答案中添加“未定义行为”并不总是意味着坏事将要发生的说法。未定义行为实际上说:“我们不提供有关XYZ发生时下一步将如何发生的任何规范”。

(* C ++标准)。

这是进行操作系统的地方,说“它是我们定义的”。

虽然铸造结构无关(sockaddr_insockaddr)可以是由标准定义的操作中,OS API指定它是与他们的API有效。


gsa*_*ras 0

它们的大小相同,所以不,您不会得到任何UB

\n

证明:

\n
#include <stdio.h>\n\nstruct sockaddr {\n  unsigned short sa_family; // address family, AF_xxx\n  char sa_data[14]; // 14 bytes of protocol address\n};\n\n// src: http://www.gta.ufrj.br/ensino/eel878/sockets/sockaddr_inman.html\nstruct in_addr {\n    unsigned long s_addr;  // load with inet_aton()\n};\n\nstruct sockaddr_in {\n  short int sin_family; // Address family, AF_INET\n  unsigned short int sin_port; // Port number\n  struct in_addr sin_addr; // Internet address\n  unsigned char sin_zero[8]; // Same size as struct sockaddr\n};\n\nint main (void) {\n  printf("%zu\\n", sizeof(unsigned short) + sizeof(char) * 14);\n  printf("%zu\\n", sizeof(short int) + sizeof(unsigned short int) + sizeof(struct in_addr) + sizeof(unsigned char) * 8);\n  return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
16\n16\n
Run Code Online (Sandbox Code Playgroud)\n

很好的评论: sockaddr: 2+14=16, sockaddr_in:2+2+4+8=16 \xe2\x80\x93 Amer Agovic

\n

您可能还想看看这个问题:Why isn't sizeof for a struct equal to the sum of sizeof of every member?

\n
\n

请检查这个问题:Is it possible tocast struct to another?

\n

我也在这里复制Benoit的答案:

\n
\n

这称为类型双关语。这里,两个结构体具有相同的大小,因此不存在结构体大小的问题。尽管您几乎可以将任何内容转换为任何内容,但使用结构进行转换很容易出错。

\n
\n

还有理查德·罗斯三世 (Richard J. Ross III) 的这一篇:

\n
\n

这是 C 的“继承”形式(注意引号)。这是可行的,因为 C 不关心地址中的基础数据,只关心您将其表示为什么。

\n

该函数通过使用 sa_family 字段来确定它实际上是什么结构,并将其转换为函数内正确的 sockaddr_in 。

\n
\n

  • 在这种情况下,它们具有“相同大小”(或不同大小)的事实绝对没有任何相关性。C 在这里也无济于事:该行为在 C 中未定义,就像在 C++ 中未定义一样。 (2认同)