6

我对定义为的函数的这个参数感到困惑

int bind(int s, const struct sockaddr *name, int namelen)

并称为

bind(sd, (struct sockaddr_in *) &addr, length);

我无法解释struct sockaddr_in *这里的意思。

这行得通吗:bind (sd, &addr, length);

4

3 回答 3

3

它应该这样调用:

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_insockaddr_in6sockaddr

于 2012-11-11T17:13:45.013 回答
2

除了void指针,从指针到T指针的转换U应该是显式的。

bind (sd, (struct sockaddr *) &addr, length);
于 2012-11-11T17:08:34.600 回答
1

这取决于是什么addr

如果它不是同一个结构的地址,那么你需要对它进行类型转换,否则你会收到隐式类型转换 from <type of addr>to 的警告const struct sockaddr*

查看编译器在编译任何程序时给出的所有警告消息。开始使用它(用于编译器gcc警告):

gcc -Wall <test.c> -o <test>

这是程序员的最佳实践。

于 2012-11-11T17:08:56.273 回答