From 54d69bcedcff24bcfe9c32ced6a5623f2ea33c27 Mon Sep 17 00:00:00 2001 From: Akemi Izuko Date: Fri, 31 Jan 2025 13:16:39 -0700 Subject: [PATCH] Lab10: add single thread udp example --- lab10/single_thread_udp.c | 143 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 lab10/single_thread_udp.c diff --git a/lab10/single_thread_udp.c b/lab10/single_thread_udp.c new file mode 100644 index 0000000..507d7ca --- /dev/null +++ b/lab10/single_thread_udp.c @@ -0,0 +1,143 @@ +#include +#include +#include +#include +#include +#include +#include + +int udp_create_server_socket() { + char* hostname = "localhost"; + char* port = "9004"; + + struct addrinfo hints = {0}; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + hints.ai_flags = AI_PASSIVE; + + struct addrinfo* res; + int ret = getaddrinfo(hostname, port, &hints, &res); + + if (ret != 0) { + perror("getaddrinfo"); + return -1; + } + + int sfd = -1; + for (struct addrinfo* rp = res; rp != NULL; rp = rp->ai_next) { + sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (sfd == -1) { + perror("socket"); + continue; + } + + int bind_errno = bind(sfd, rp->ai_addr, rp->ai_addrlen); + if (bind_errno == -1) { + perror("bind"); + close(sfd); + sfd = -1; + continue; + } + + break; + } + + freeaddrinfo(res); + + if (sfd == -1) { + fprintf(stderr, "Failed to create socket\n"); + close(sfd); + return -1; + } + + return sfd; +} + +int udp_client_socket(struct sockaddr** socket_addr, socklen_t* addr_len) { + char* hostname = "localhost"; + char* port = "9004"; + + struct addrinfo hints = {0}; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + + struct addrinfo* res; + int ret_err = getaddrinfo(hostname, port, &hints, &res); + + if (ret_err != 0) { + perror("getaddrinfo"); + return -1; + } + + int sfd; + for (struct addrinfo* rp = res; rp != NULL; rp = rp->ai_next) { + sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (sfd == -1) { + perror("socket"); + continue; + } + + *socket_addr = rp->ai_addr; + *socket_addr = malloc(rp->ai_addrlen); + memcpy(*socket_addr, rp->ai_addr, rp->ai_addrlen); + *addr_len = rp->ai_addrlen; + break; + } + + freeaddrinfo(res); + if (sfd == -1) { + fprintf(stderr, "Failed to create socket\n"); + close(sfd); + return -1; + } + + return sfd; +} + +int main(void) { + struct sockaddr* socket_addr; + socklen_t addr_len; + + int sfd_server = udp_create_server_socket(); + int sfd_client = udp_client_socket(&socket_addr, &addr_len); + + printf("Got a server socket: %d\n", sfd_server); + printf("Got a client socket: %d\n", sfd_client); + + if (sfd_server == -1 || sfd_client == -1) { + if (sfd_server != -1) close(sfd_server); + if (sfd_client != -1) close(sfd_client); + return 1; + } + + sleep(10); + + char* my_string = "one two three"; + + int ret = sendto( + sfd_client, + my_string, + strlen(my_string) + 1, + 0, + socket_addr, + addr_len + ); + if (ret == -1) { + perror("send"); + return 0; + } + + char buf[10000]; + ret = recv(sfd_server, (void*) buf, 10000 * sizeof(char), 0); + if (ret == -1) { + perror("recv"); + return 0; + } + + printf("OMG, I just totes got a message: `%s`\n", buf); + + close(sfd_server); + close(sfd_client); +}