我对定义为的函数的这个参数感到困惑
int bind(int s, const struct sockaddr *name, int namelen)
并称为
bind(sd, (struct sockaddr_in *) &addr, length);
我无法解释struct sockaddr_in *
这里的意思。
这行得通吗:bind (sd, &addr, length);
?
它应该这样调用:
bind (sd, (struct sockaddr *) &addr, length);
至于为什么,这是做多态的C方式,如果你看一下这些结构的定义:
struct sockaddr {
unsigned short sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address
};
// IPv4 AF_INET sockets:
struct sockaddr_in {
short sin_family; // e.g. AF_INET, AF_INET6
unsigned short sin_port; // e.g. htons(3490)
struct in_addr sin_addr; // see struct in_addr, below
char sin_zero[8]; // zero this if you want to
};
// IPv6 AF_INET6 sockets:
struct sockaddr_in6 {
u_int16_t sin6_family; // address family, AF_INET6
u_int16_t sin6_port; // port number, Network Byte Order
u_int32_t sin6_flowinfo; // IPv6 flow information
struct in6_addr sin6_addr; // IPv6 address
u_int32_t sin6_scope_id; // Scope ID
};
它们都共享相同的第一个成员,sa_family
当您将指向其中一个结构的指针传递给bind()
您首先将其转换struct sockaddr *
为函数并在函数内部时,sa_family
用于确定您传递的结构并转换回正确的结构,而不是拥有一个函数对于每个结构,您都有一个接受sockaddr*
.
另一种看待它的方式,从 OOP 的角度来看,想象它是andsockaddr
的基类,并且传递一个指针类似于强制转换为基类型并调用一个泛型函数。希望这更清楚。sockaddr_in
sockaddr_in6
sockaddr
除了void
指针,从指针到T
指针的转换U
应该是显式的。
bind (sd, (struct sockaddr *) &addr, length);
这取决于是什么addr
。
如果它不是同一个结构的地址,那么你需要对它进行类型转换,否则你会收到隐式类型转换 from <type of addr>
to 的警告const struct sockaddr*
查看编译器在编译任何程序时给出的所有警告消息。开始使用它(用于编译器gcc
警告):
gcc -Wall <test.c> -o <test>
这是程序员的最佳实践。