aboutsummaryrefslogtreecommitdiff
path: root/reference.c
diff options
context:
space:
mode:
Diffstat (limited to 'reference.c')
-rw-r--r--reference.c109
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