aboutsummaryrefslogtreecommitdiff
path: root/src/socket.c
diff options
context:
space:
mode:
authorkartofen <mladenovnasko0@gmail.com>2022-08-31 12:31:38 +0300
committerkartofen <mladenovnasko0@gmail.com>2022-08-31 12:31:38 +0300
commit675ded0d66b9fd60777d3037ded1446a3f9ef986 (patch)
tree6db3f0524437304f9e5a7b90175e3f6b043d4d49 /src/socket.c
Big Bang
Diffstat (limited to 'src/socket.c')
-rw-r--r--src/socket.c153
1 files changed, 153 insertions, 0 deletions
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 <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#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 <time.h>
+ 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;
+}