diff options
author | oskar <[email protected]> | 2024-05-22 20:11:10 +0200 |
---|---|---|
committer | oskar <[email protected]> | 2024-05-22 20:11:10 +0200 |
commit | 330c22b13e46f3ba51d5c2775235da2276dca8a0 (patch) | |
tree | e960aa230ed1ecfd9f144e9aae0b16c353443f78 |
networking learning
-rw-r--r-- | Makefile | 36 | ||||
-rw-r--r-- | README | 1 | ||||
-rw-r--r-- | binding.c | 45 | ||||
-rw-r--r-- | connecting.c | 36 | ||||
-rw-r--r-- | hello.c | 69 | ||||
-rw-r--r-- | listen.c | 83 | ||||
-rw-r--r-- | test/Makefile | 6 |
7 files changed, 276 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..af9fd70 --- /dev/null +++ b/Makefile @@ -0,0 +1,36 @@ +CC=egcc +CFLAGS_TESTBIN=-O3 -Wfatal-errors -Wall -Werror -Wextra -g -Wpedantic -std=gnu99 +CFLAGS=-O3 -flto -march=native -DNDEBUG -fomit-frame-pointer -s -std=gnu99 +MAKEFLAGS += -j$(nproc) +TARGETS=helloworld +TARGETS2=binding +TARGETS3=listen +TARGETS4=connecting +TARGETS5= +TESTTARGET=helloworld-t +TESTTARGET2=binding-t +TESTTARGET3=listen-t +TESTTARGET4=connecting-t +TESTTARGET5= +SRCS=hello.c +SRCS2=binding.c +SRCS3=listen.c +SRCS4=connecting.c +SRCS5= + +all: release +clean: + rm -f bin/$(TARGETS) bin/$(TARGETS2) bin/$(TARGETS3) bin/$(TARGETS4) + rm -f test/$(TESTTARGET) test/$(TESTTARGET2) test/$(TESTTARGET3) test/$(TESTTARGET4) + +tests: + $(CC) $(CFLAGS_TESTBIN) $(SRCS) -o test/$(TESTTARGET) + $(CC) $(CFLAGS_TESTBIN) $(SRCS2) -o test/$(TESTTARGET2) + $(CC) $(CFLAGS_TESTBIN) $(SRCS3) -o test/$(TESTTARGET3) + $(CC) $(CFLAGS_TESTBIN) $(SRCS4) -o test/$(TESTTARGET4) + +release: + $(CC) $(CFLAGS) $(SRCS) -o bin/$(TARGETS) + $(CC) $(CFLAGS) $(SRCS2) -o bin/$(TARGETS2) + $(CC) $(CFLAGS) $(SRCS3) -o bin/$(TARGETS3) + $(CC) $(CFLAGS) $(SRCS4) -o bin/$(TARGETS4) @@ -0,0 +1 @@ +Im trying to learn networking diff --git a/binding.c b/binding.c new file mode 100644 index 0000000..ebc503d --- /dev/null +++ b/binding.c @@ -0,0 +1,45 @@ +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <unistd.h> +#include <stdbool.h> +#include <fcntl.h> +#include <stdlib.h> +#include <arpa/inet.h> +#include <netinet/in.h> + +#define _FAIL_EXIT -1 + +// Bind section of beej networking + +int main () { + + struct addrinfo hints; + struct addrinfo *res; + int sockfd; + int status; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + status = getaddrinfo(NULL, "61000", &hints, &res); + if(status != 0) { + fprintf(stderr, "Error: %s\n", gai_strerror(status)); + exit(_FAIL_EXIT); + } + + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (sockfd == -1) { + exit(_FAIL_EXIT); + } + + int bstatus; + bstatus = bind(sockfd, res->ai_addr, res->ai_addrlen); + + fprintf(stdout, "%d\n", bstatus); + return 0; + +} diff --git a/connecting.c b/connecting.c new file mode 100644 index 0000000..fe9b99e --- /dev/null +++ b/connecting.c @@ -0,0 +1,36 @@ +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <unistd.h> +#include <stdbool.h> +#include <fcntl.h> +#include <stdlib.h> +#include <arpa/inet.h> +#include <netinet/in.h> + +int main () { + + int sockfd; + struct addrinfo *res; + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + int result = getaddrinfo("192.168.1.18", "62000", &hints, &res); + if (result != 0) { + exit(0); + } + + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + int connect_res = connect(sockfd, res->ai_addr, res->ai_addrlen); + if (connect_res == -1) { + fprintf(stderr, "connect_res: -1\n"); + exit(1); + } + + + return 0; +} @@ -0,0 +1,69 @@ +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <unistd.h> +#include <stdbool.h> +#include <fcntl.h> +#include <stdlib.h> +#include <arpa/inet.h> +#include <netinet/in.h> + +// BEEJ NETWORKING 5.1 + +int main (int argc, char *argv[]) { + + if (argc > 2 || argc == 1) { + fprintf(stderr, "Too many or not enough arguments! \n"); + fprintf(stderr, "USAGE: getip [DOMAIN]\n"); + exit(1); + } + char ipstr[INET_ADDRSTRLEN]; // We store the IP address in text form here. INET_ADDRSTRLEN is the length of ipv4 addresses. + int status; + struct addrinfo hints; // Struct where we put information in to pass it to getaddrinfo. + struct addrinfo *res; // The result of getaddrinfo. Not sure why its a pointer but ill figure that out later + struct addrinfo *rescpy; // Another rescpy struct pointer. This one is used to point to the next element when iterating in a for loop. + memset(&hints, 0, sizeof hints); // Set all values to 0 in hints. + hints.ai_family = AF_INET; // Add the necessary info to ai_family, ai_socktype, ai_flags. + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + + status = getaddrinfo(argv[1], "62222", &hints, &res); // get addrinfo. Address to hints and res passed. + if (status != 0) { + fprintf(stderr, "Error: %s\n", gai_strerror(status)); + exit(1); + } + + // rescpy = res. Both point to the same result. + // rescpy != NULL. If its NULL then the next struct in the linked list is the last one. + // rescpy = rescpy->ai_next. After it did the loop it goes back, checks if its null. If not then rescpy is assigned the pointer to ai_next. And so on and so on. + // A visual representation: + // + // res --> GAI_RESULT_STRUCT (res points to the result addrinfo struct) + // rescpy = res (BOTH POINT TO GAI_RESULT_STRUCT) + // IF rescpy is not NULL + // + // rescpy = rescpy --> ai_next (Its easier for me to imagine this line with some different syntax: rescpy = rescpy.ai_next. This is technically not correct but this is for my eyes only.) + // ai_next is a pointer to another addrinfo struct. Which is the next item in the linked list. rescpy = rescpy --> ai_next, this basically means we access the ai_next member + // which is inside GAI_RESULT_STRUCT. We basically make rescpy point to the next item. + // + // + + for(rescpy = res ; rescpy != NULL ; rescpy = rescpy->ai_next) { + struct sockaddr_in *sa1 = (struct sockaddr_in *)rescpy->ai_addr; // struct sockaddr_in sa1 pointer assigned ai_addr. sa1 now points to ai_addr. + // ai_addr may be a sockaddr_in or a sockaddr_in6. + // We cast it to sockaddr_in which is supposed to just work. + void *addr = &(sa1->sin_addr); // Address of sin_addr. sa1 now points to ai_addr so we access the item sin_addr and make addr point to it. + inet_ntop(rescpy->ai_family, addr, ipstr, rescpy->ai_addrlen); + + fprintf(stdout, "%s\n", ipstr); + + } + + freeaddrinfo(res); + + return 0; + +} diff --git a/listen.c b/listen.c new file mode 100644 index 0000000..8557a60 --- /dev/null +++ b/listen.c @@ -0,0 +1,83 @@ +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <unistd.h> +#include <stdbool.h> +#include <fcntl.h> +#include <stdlib.h> +#include <arpa/inet.h> +#include <netinet/in.h> + +// int listen(int sockfd, int backlog); + +#define BACKLOG 2 + +int main () { + + int sockfd; + int gai_result; + int bind_result; + struct addrinfo *res; + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + + gai_result = getaddrinfo(NULL, "62000", &hints, &res); + if (gai_result != 0) { + fprintf(stderr, "gai_result: %d\n", gai_result); + exit(1); + } + + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (sockfd == -1) { + fprintf(stderr, "sockfd: %d\n", sockfd); + exit(1); + } + + bind_result = bind(sockfd, res->ai_addr, res->ai_addrlen); + if (bind_result != 0) { + fprintf(stderr, "bind_result: %d\n", bind_result); + exit(1); + } + + listen(sockfd, BACKLOG); + socklen_t addr_size; + struct sockaddr_storage their_addr; + addr_size = sizeof(their_addr); + int newfd; + newfd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size); + if (newfd == -1) { + fprintf(stderr, "newfd: %d\n", newfd); + exit(1); + } + + char *msg = "Server says hi!\n"; + int len; + int bytes_sent; + len = strlen(msg); + bytes_sent = send(newfd, msg, len, 0); + + int rlen = 1000; + int recv_ret; + size_t bytes_recieved = 0; + while(true) { + + char recvmsg[rlen]; + recv_ret = recv(newfd, recvmsg, rlen, 0); + bytes_recieved = bytes_recieved+recv_ret; + if (recv_ret < 1) { + break; + } + recvmsg[recv_ret] = '\0'; + fprintf(stdout, "%s", recvmsg); + memset(&recvmsg, 0, (size_t)rlen); + } + fprintf(stdout, "bytes recieved: %ld\nbytes sent: %d\n", bytes_recieved, bytes_sent); + + return 0; +} diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..48a5814 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,6 @@ +all: release +clean: + cd .. && make clean + +release: + cd .. && make tests |