Socket Programming, Casting sockaddr_in to sockaddr. Why?

Here is a sample socket programming snippet from the client side. My question revolves around the type-casting that casted sockaddr_in into sockaddr. My question is that why is that casting necessary there, what is going on there exactly?

#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 8080
int main ( int argument, char const *argv[] )
{
int obj_socket = 0, reader;
struct sockaddr_in serv_addr;
char *message = "A message from Client !";
char buffer[1024] = {0};
if (( obj_socket = socket (AF_INET, SOCK_STREAM, 0 )) < 0)
{
printf ( "Socket creation error !" );
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if(inet_pton ( AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
{
printf ( "\nInvalid address ! This IP Address is not supported !\n" );
return -1;
}
if ( connect( obj_socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr )) < 0) // <--- QUESTION ABOUT THIS LINE
{
Printf ( "Connection Failed : Can't establish a https://www.alaskasworld.me/ over this socket !" );
return -1;
}
send ( obj_socket , message , strlen(message) , 0 );
printf ( "\nClient : Message has been sent !\n" );
reader = read ( obj_socket, buffer, 1024 );
printf ( "%s\n",buffer );
return 0;
}
Last edited on
Use code tags when posting code.

sockaddr is a generic structure that has its first member in common with multiple other specific structures, such as sockaddr_in. This allows different specific structures (e.g., sockaddr_in6) to be passed to various functions, which all take the generic sockaddr. That's why you need to set the first member to AF_INET, which just identifies it as the sockaddr_in struct. It's a kind of polymorphism for C.

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <stdio.h>

typedef struct {
    int type;
} Generic;

typedef struct {
    int type;
    int a;
    int b;
} Specific1;

typedef struct {
    int type;
    const char* s;
} Specific2;

enum { Spec1, Spec2 };

void display(Generic *g) {
    switch (g->type) {
        case Spec1: {
            Specific1 *s = (Specific1*)g;
            printf("%d %d\n", s->a, s->b);
            break;
        }
        case Spec2: {
            Specific2 *s = (Specific2*)g;
            printf("%s\n", s->s);
            break;
        }
    }
}

int main() {
    Specific1 s1 = {Spec1, 21, 42};
    Specific2 s2 = {Spec2, "hello"};
    display((Generic*)&s1);
    display((Generic*)&s2);
    return 0;
}

Topic archived. No new replies allowed.