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;
}
Milad Khajavi
  • 2,769
  • 9
  • 41
  • 66

4 Answers4

10

This is refered as Type Punning. Here, both structures have the same size, so there is no question of struct size. Although you can cast almost anything to anything, doing it with structures is error-prone.

Benny
  • 4,095
  • 1
  • 26
  • 27
6

This is C's form of "inheritance" (notice the quotes). This works because C does not care about the underlying data in an address, just what you represent it as.

The function determines what structure it actually is by using the sa_family field, and casting it into the proper sockaddr_in inside the function.

Richard J. Ross III
  • 55,009
  • 24
  • 135
  • 201
3

You can cast sockaddr_in to sockaddr, but you cannot usually cast ANY struct to ANY other and assume that things will work properly.

mathematician1975
  • 21,161
  • 6
  • 59
  • 101
1

In C, it's possible to cast anything to anything. You could even omit the cast to (struct sockaddr*), and probably just get a compiler warning.

gcbenison
  • 11,723
  • 4
  • 44
  • 82