If you are confused by why a pointer to server, which I assume is of type sockaddr_in is not passed to the function and instead it is cast to a pointer to struct sockaddr, then here is your answer:
The struct sockaddr_in is just a wrapper structure for struct sockaddr:
struct sockaddr {
    unsigned short sa_family;
    char           sa_data[14];
};
The port number and the ip address are held together here. They are held together in sa_data[14]-  the first 2 bytes holding the port number, and the next 4 bytes holding the ip address. The remaining 8 bytes are unused. These are the 8 bytes you clear to zeroes via sin_zero[8] when you use sockaddr_in.
Functions like connect() does not know of any type struct sockaddr_in, they only know of struct sockaddr.