为什么从sockaddr_in强制转换为sockaddr [英] Why does a cast from sockaddr_in to sockaddr work
问题描述
在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_in
到sockaddr
的转换有效,因为我找不到任何文件来说明为什么有效.
似乎每个人都在做.
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屋!