#include #include #include #include #include #include #include struct addrinfo { int ai_flags; // AI_PASSIVE, AI_CANONNAME, etc. int ai_family; // AF_INET, AF_INET6, AF_UNSPEC int ai_socktype; // SOCK_STREAM, SOCK_DGRAM int ai_protocol; // use 0 for "any" size_t ai_addrlen; // size of ai_addr in bytes struct sockaddr *ai_addr; // struct sockaddr_in or _in6 char *ai_canonname; // full canonical hostname struct addrinfo *ai_next; // linked list, next node }; struct sockaddr { unsigned short sa_family; // address family, AF_xxx char sa_data[14]; // 14 bytes of protocol address }; struct sockaddr_in { short int sin_family; // Address family, AF_INET unsigned short int sin_port; // Port number struct in_addr sin_addr; // Internet address unsigned char sin_zero[8]; // Same size as struct sockaddr }; // (IPv4 only--see struct in6_addr for IPv6) // Internet address (a structure for historical reasons) struct in_addr { uint32_t s_addr; // that's a 32-bit int (4 bytes) }; struct sockaddr_storage { sa_family_t ss_family; // address family // all this is padding, implementation specific, ignore it: char __ss_pad1[_SS_PAD1SIZE]; int64_t __ss_align; char __ss_pad2[_SS_PAD2SIZE]; }; int getaddrinfo(const char *node, // e.g. "www.example.com" or IP const char *service, // e.g. "http" or port number const struct addrinfo *hints, struct addrinfo **res); // sockets! #include #include int socket(int domain, int type, int protocol); int s; struct addrinfo hints, *res; // do the lookup // [pretend we already filled out the "hints" struct] getaddrinfo("www.example.com", "http", &hints, &res); // again, you should do error-checking on getaddrinfo(), and walk // the "res" linked list looking for valid entries instead of just // assuming the first one is good (like many of these examples do). // See the section on client/server for real examples. s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);