#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; }