FreeCalypso > hg > rtp-debug-utils
comparison udp-test-sink.c @ 9:c00510e1ae8b
new program udp-test-sink
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 10 Mar 2024 02:27:37 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
8:d180987db615 | 9:c00510e1ae8b |
---|---|
1 /* | |
2 * This program is a simple sink for UDP: it binds to a UDP port and sinks | |
3 * (reads and discards) all packets that arrive at it. Upon receiving a | |
4 * burst or stream of packets followed by a prolonged pause, it prints | |
5 * the number of packets that were received. | |
6 */ | |
7 | |
8 #include <sys/types.h> | |
9 #include <sys/socket.h> | |
10 #include <sys/time.h> | |
11 #include <sys/errno.h> | |
12 #include <netinet/in.h> | |
13 #include <arpa/inet.h> | |
14 #include <stdio.h> | |
15 #include <stdlib.h> | |
16 #include <string.h> | |
17 #include <strings.h> | |
18 #include <unistd.h> | |
19 | |
20 static void | |
21 parse_ip_port(arg, sin) | |
22 char *arg; | |
23 struct sockaddr_in *sin; | |
24 { | |
25 char *cp; | |
26 int rc; | |
27 | |
28 cp = index(arg, ':'); | |
29 if (!cp) { | |
30 fprintf(stderr, "error: missing ':' in IP:port argument\n"); | |
31 exit(1); | |
32 } | |
33 *cp++ = '\0'; | |
34 sin->sin_family = AF_INET; | |
35 rc = inet_aton(arg, &sin->sin_addr); | |
36 if (!rc) { | |
37 fprintf(stderr, "error: invalid IP address argument\n"); | |
38 exit(1); | |
39 } | |
40 sin->sin_port = htons(atoi(cp)); | |
41 } | |
42 | |
43 main(argc, argv) | |
44 char **argv; | |
45 { | |
46 struct sockaddr_in bindsin; | |
47 int udp_fd, rc; | |
48 unsigned idle_sec, rx_count; | |
49 fd_set fds; | |
50 struct timeval tv; | |
51 u_char dummybuf[256]; | |
52 | |
53 if (argc < 2 || argc > 3) { | |
54 fprintf(stderr, "usage: bind-IP:port [idle-sec]\n", argv[0]); | |
55 exit(1); | |
56 } | |
57 parse_ip_port(argv[1], &bindsin); | |
58 if (argc >= 3) | |
59 idle_sec = atoi(argv[2]); | |
60 else | |
61 idle_sec = 0; | |
62 udp_fd = socket(AF_INET, SOCK_DGRAM, 0); | |
63 if (udp_fd < 0) { | |
64 perror("socket(AF_INET, SOCK_DGRAM, 0)"); | |
65 exit(1); | |
66 } | |
67 rc = bind(udp_fd, (struct sockaddr *) &bindsin, sizeof bindsin); | |
68 if (rc < 0) { | |
69 perror("bind"); | |
70 exit(1); | |
71 } | |
72 for (rx_count = 0; ; ) { | |
73 FD_ZERO(&fds); | |
74 FD_SET(udp_fd, &fds); | |
75 if (rx_count && idle_sec) { | |
76 tv.tv_sec = idle_sec; | |
77 tv.tv_usec = 0; | |
78 rc = select(udp_fd+1, &fds, 0, 0, &tv); | |
79 } else | |
80 rc = select(udp_fd+1, &fds, 0, 0, 0); | |
81 if (rc < 0) { | |
82 if (errno == EINTR) | |
83 continue; | |
84 perror("select"); | |
85 exit(1); | |
86 } | |
87 if (FD_ISSET(udp_fd, &fds)) { | |
88 recv(udp_fd, dummybuf, sizeof dummybuf, 0); | |
89 rx_count++; | |
90 } else { | |
91 printf("Received %u packet%s\n", rx_count, | |
92 rx_count != 1 ? "s" : ""); | |
93 rx_count = 0; | |
94 } | |
95 } | |
96 } |