为什么从sockaddr_in强制转换为sockaddr [英] Why does a cast from sockaddr_in to sockaddr work

查看:117
本文介绍了为什么从sockaddr_in强制转换为sockaddr的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C语言中,bind套接字的典型方法如下:

In the C language a typical way to bind a Socket would be the following way:

int server_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
int port_number = 55555;

addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port_number);

int result = bind(server_socket_fd,(struct sockaddr *)&addr , sizeof(addr));
if(bind_result > 0)
{
    // Stuff
}

我想知道为什么从sockaddr_insockaddr的转换有效,因为我找不到任何文件来说明为什么有效. 似乎每个人都在做.

I am wondering why the cast from sockaddr_in to sockaddr works since I cant find any documentation why it works. It just seems like everyone just does it.

为什么类型转换在这里起作用?

Why does the typecast work here?

我不是在问我们为什么要投射它,这已经得到回答

I am not asking why we cast it, this has been answered here. I am asking why it works.

推荐答案

sockaddr结构基本上只有一个字段,即地址族.接收此结构的代码可以使用此字段来确定结构的实际类型是什么.实际使用的所有结构也都以该字段为第一个字段,因此该值是确定的.

The sockaddr struct basically has only one field, the address family. The code that receives this structure can use this field to determine what is the actual type of the structure. All the structures that are really used also have this field as the first one and therefore the value is deterministic.

实现还使结构具有相同的填充大小,因此内存使用情况也完全是确定性的.这样可以使其正常工作.

The implementations also make the structures the same size with padding, so the memory usage is also completely deterministic. This makes it work properly.

例如,Microsoft定义了 sockaddr 在Visual Studio 2017中的结构为

For example Microsoft defines the sockaddr structure in Visual Studio 2017 as

struct sockaddr {  
    unsigned short sa_family;  
    char sa_data[14];  
};

sa_data
所有不同套接字地址结构的最大大小.

sa_data
Maximum size of all the different socket address structures.

因此,可能发送的任何子"结构中必须包含14个字节的数据,或多或少.

So any "child" struct that may be sent must have 14 bytes of data in it, no more or less.

sockaddr_in

struct sockaddr_in{  
    short sin_family;  
    unsigned short sin_port;  
struct in_addr sin_addr;  
    char sin_zero[8];  
};

此处的端口和in_addr总共需要六个字节,因此使用8个字节的填充来保持大小与sockaddr相同.

Here the port and in_addr require six bytes in total so 8 bytes of padding is used to keep the size the same as sockaddr.

当然,可以创建例如sockaddr_un,设置其地址族以声明其为sockaddr_in,并且任何接收该结构的代码都会将其转换为错误并获得完全错误的值.

Of course it would be possible to create for example sockaddr_un, set its address family to claim it’s sockaddr_in and any code receiving the structure would cast it wrong and get completely wrong values.

这篇关于为什么从sockaddr_in强制转换为sockaddr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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