From 675ded0d66b9fd60777d3037ded1446a3f9ef986 Mon Sep 17 00:00:00 2001 From: kartofen Date: Wed, 31 Aug 2022 12:31:38 +0300 Subject: Big Bang --- src/socket.c | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/socket.c (limited to 'src/socket.c') diff --git a/src/socket.c b/src/socket.c new file mode 100644 index 0000000..e388e45 --- /dev/null +++ b/src/socket.c @@ -0,0 +1,153 @@ +#include +#include +#include +#include +#include +#include +#include +#include "socket.h" +#include "typedef.h" + +void *get_in_addr(struct sockaddr *sa) +{ + if (sa->sa_family == AF_INET) { + return &(((struct sockaddr_in*)sa)->sin_addr); + } + + return &(((struct sockaddr_in6*)sa)->sin6_addr); +} + +int listener(char *port, void (*on_recv)(char *, int)) +{ + int sockfd; + int ret; + + struct addrinfo hints, *servinfo; + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_INET6; // set to AF_INET to use IPv4 + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_PASSIVE; // use my IP + + int rv; + if((rv = getaddrinfo(NULL, port, &hints, &servinfo)) != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); + return 1; + } + + struct addrinfo *p; + for(p = servinfo; p != NULL; p = p->ai_next) + { + if((sockfd = socket(p->ai_family, p->ai_socktype, + p->ai_protocol)) == -1) { + perror("listener: socket"); + continue; + } + + if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { + close(sockfd); + perror("listener: bind"); + continue; + } + + break; + } + + if(p == NULL) { + fprintf(stderr, "listener: failed to bind socket\n"); + return 2; + } + + freeaddrinfo(servinfo); + + #include + int i = 0; + time_t now = 0; + while(1) + { + if(now < time(NULL)) { + now = time(NULL); + printf("FPS: %d\n", i); + i = 0; + } + + char buf[BUF_CAP] = {0}; + struct sockaddr_storage their_addr; + socklen_t addr_len = sizeof(their_addr); + + int numbytes; + if ((numbytes = recvfrom(sockfd, buf, BUF_CAP-1 , 0, + (struct sockaddr *)&their_addr, &addr_len)) == -1) { + perror("recvfrom"); + return 1; + } + + #ifdef LOG_INFO_STDOUT + char s[INET6_ADDRSTRLEN]; + printf("listener: got packet from %s, %d bytes long\n", + inet_ntop(their_addr.ss_family, + get_in_addr((struct sockaddr *)&their_addr), + s, sizeof(s)), numbytes); + #endif + + on_recv(buf, numbytes); + + i++; + } + + return 0; +} + +int talker(char *port, char *address, void (*on_send)(char *, int *)) +{ + int sockfd; + + struct addrinfo hints, *servinfo; + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_INET6; // set to AF_INET to use IPv4 + hints.ai_socktype = SOCK_DGRAM; + + int rv; + if((rv = getaddrinfo(address, port, &hints, &servinfo)) != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); + return 1; + } + + struct addrinfo *p; + for(p = servinfo; p != NULL; p = p->ai_next) + { + if((sockfd = socket(p->ai_family, p->ai_socktype, + p->ai_protocol)) == -1) { + perror("talker: socket"); + continue; + } + + break; + } + + if(p == NULL) { + fprintf(stderr, "talker: failed to create socket\n"); + return 2; + } + + while(1) + { + char buf[BUF_CAP] = {0}; + int bytes; + on_send(buf, &bytes); + + int numbytes; + if((numbytes = sendto(sockfd, buf, bytes, 0, + p->ai_addr, p->ai_addrlen)) == -1) { + perror("talker: sendto"); + return 1; + } + #ifdef LOG_INFO_STDOUT + printf("talker: sent %d bytes to %s\n", numbytes, address); + #endif + } + + freeaddrinfo(servinfo); + close(sockfd); + + return 0; +} -- cgit v1.2.3