14

Any one could describe how (struct sockaddr *)&server works here? Is it possible to cast bigger struct to smaller struct?

See these structs:

// 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
};

struct in_addr {
    unsigned long s_addr;          // load with inet_pton()
};

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

This is the main program:

int main(int argc , char *argv[])
 {
        int socket_desc;
        struct sockaddr_in server;

    //Create socket
    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1)
    {
        printf("Could not create socket");
    }

    server.sin_addr.s_addr = inet_addr("74.125.235.20");
    server.sin_family = AF_INET;
    server.sin_port = htons( 80 );

    //Connect to remote server
    if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0)
    {
        puts("connect error");
        return 1;
    }

    puts("Connected");
    return 0;
}
4

4 に答える 4

10

これは、型パニングと呼ばれます。ここでは、両方の構造体のサイズが同じであるため、構造体のサイズの問題はありません。ほとんど何でも何でもキャストできますが、構造体でキャストするとエラーが発生しやすくなります。

于 2012-06-12T14:23:39.787 に答える
6

これは C の「継承」の形式です (引用符に注意してください)。これが機能するのは、C がアドレスの基になるデータを気にせず、それを何として表現するかだけだからです。

この関数は、sa_family フィールドを使用して実際の構造を決定し、それをsockaddr_in関数内の適切な場所にキャストします。

于 2012-06-12T14:24:42.730 に答える
3

sockaddr_in を sockaddr にキャストすることはできますが、通常、構造体を他の構造体にキャストして、正常に機能すると仮定することはできません。

于 2012-06-12T14:24:35.017 に答える
1

C では、何でもキャストできます。(struct sockaddr*) へのキャストを省略することもでき、おそらくコンパイラの警告が表示されるだけです。

于 2012-06-12T14:25:32.143 に答える