1 /* 2 * Copyright 2010, Atis Elsts, the.kfx@gmail.com 3 * Distributed under the terms of the MIT license. 4 */ 5 6 7 #include <unistd.h> 8 #include <memory.h> 9 #include <netinet/in.h> 10 #include <netinet/ip.h> 11 #include <arpa/inet.h> 12 #include <errno.h> 13 #include <stdio.h> 14 #include <stdlib.h> 15 16 17 const unsigned short TEST_PORT = 40000; 18 19 20 void 21 recvLoop(int fd) 22 { 23 for (;;) { 24 char buffer[1000]; 25 sockaddr_storage address; 26 socklen_t socklen = sizeof(address); 27 memset(&address, 0, socklen); 28 29 int status = recvfrom(fd, buffer, sizeof(buffer) - 1, 0, 30 (sockaddr *) &address, &socklen); 31 if (status < 0) { 32 perror("recvfrom"); 33 exit(-1); 34 } 35 if (status == 0) { 36 printf("received EOF!\n"); 37 break; 38 } else { 39 buffer[status] = 0; 40 printf("received %d bytes: \"%s\"\n", status, buffer); 41 } 42 } 43 } 44 45 46 int 47 main(int argc, char *argv[]) 48 { 49 int socketFamily = AF_INET; 50 51 if (argc > 1) { 52 if (!strcmp(argv[1], "-4")) 53 socketFamily = AF_INET; 54 else if (!strcmp(argv[1], "-6")) 55 socketFamily = AF_INET6; 56 } 57 58 int fd = socket(socketFamily, SOCK_DGRAM, 0); 59 if (fd < 0) { 60 perror("socket"); 61 return -1; 62 } 63 64 sockaddr_storage localAddress; 65 memset(&localAddress, 0, sizeof(localAddress)); 66 if (socketFamily == AF_INET) { 67 sockaddr_in *sa = (sockaddr_in *) &localAddress; 68 sa->sin_family = AF_INET; 69 sa->sin_port = htons(TEST_PORT); 70 } else { 71 sockaddr_in6 *sa = (sockaddr_in6 *) &localAddress; 72 sa->sin6_family = AF_INET6; 73 sa->sin6_port = htons(TEST_PORT); 74 // loopback 75 sa->sin6_addr.s6_addr[15] = 0x01; 76 } 77 78 if (bind(fd, (sockaddr *)&localAddress, socketFamily == AF_INET ? 79 sizeof(sockaddr_in) : sizeof(sockaddr_in6)) < 0) { 80 perror("bind"); 81 return -1; 82 } 83 84 for (;;) 85 recvLoop(fd); 86 } 87