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
recvLoop(int fd)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
main(int argc,char * argv[])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