diff options
Diffstat (limited to 'reference.c')
-rw-r--r-- | reference.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/reference.c b/reference.c new file mode 100644 index 0000000..8ec6271 --- /dev/null +++ b/reference.c @@ -0,0 +1,109 @@ +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <arpa/inet.h> +#include <netinet/in.h> + +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 <sys/types.h> +#include <sys/socket.h> + +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); + +// order is +getaddrinfo(); +socket(); +bind(); +listen(); +/* accept() goes here */ + +#include <sys/types.h> +#include <sys/socket.h> + +int sendall(int s, char *buf, int *len) +{ + int total = 0; // how many bytes we've sent + int bytesleft = *len; // how many we have left to send + int n; + + while(total < *len) { + n = send(s, buf+total, bytesleft, 0); + if (n == -1) { break; } + total += n; + bytesleft -= n; + } + + *len = total; // return number actually sent here + + return n==-1?-1:0; // return -1 on failure, 0 on success +} + +char buf[10] = "Beej!"; +int len; + +len = strlen(buf); +if (sendall(s, buf, &len) == -1) { + perror("sendall"); + printf("We only sent %d bytes because of the error!\n", len); +}
\ No newline at end of file |