diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/udp-test-sink.c	Sun Mar 10 02:27:37 2024 +0000
@@ -0,0 +1,96 @@
+/*
+ * This program is a simple sink for UDP: it binds to a UDP port and sinks
+ * (reads and discards) all packets that arrive at it.  Upon receiving a
+ * burst or stream of packets followed by a prolonged pause, it prints
+ * the number of packets that were received.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/errno.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+
+static void
+parse_ip_port(arg, sin)
+	char *arg;
+	struct sockaddr_in *sin;
+{
+	char *cp;
+	int rc;
+
+	cp = index(arg, ':');
+	if (!cp) {
+		fprintf(stderr, "error: missing ':' in IP:port argument\n");
+		exit(1);
+	}
+	*cp++ = '\0';
+	sin->sin_family = AF_INET;
+	rc = inet_aton(arg, &sin->sin_addr);
+	if (!rc) {
+		fprintf(stderr, "error: invalid IP address argument\n");
+		exit(1);
+	}
+	sin->sin_port = htons(atoi(cp));
+}
+
+main(argc, argv)
+	char **argv;
+{
+	struct sockaddr_in bindsin;
+	int udp_fd, rc;
+	unsigned idle_sec, rx_count;
+	fd_set fds;
+	struct timeval tv;
+	u_char dummybuf[256];
+
+	if (argc < 2 || argc > 3) {
+		fprintf(stderr, "usage: bind-IP:port [idle-sec]\n", argv[0]);
+		exit(1);
+	}
+	parse_ip_port(argv[1], &bindsin);
+	if (argc >= 3)
+		idle_sec = atoi(argv[2]);
+	else
+		idle_sec = 0;
+	udp_fd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (udp_fd < 0) {
+		perror("socket(AF_INET, SOCK_DGRAM, 0)");
+		exit(1);
+	}
+	rc = bind(udp_fd, (struct sockaddr *) &bindsin, sizeof bindsin);
+	if (rc < 0) {
+		perror("bind");
+		exit(1);
+	}
+	for (rx_count = 0; ; ) {
+		FD_ZERO(&fds);
+		FD_SET(udp_fd, &fds);
+		if (rx_count && idle_sec) {
+			tv.tv_sec = idle_sec;
+			tv.tv_usec = 0;
+			rc = select(udp_fd+1, &fds, 0, 0, &tv);
+		} else
+			rc = select(udp_fd+1, &fds, 0, 0, 0);
+		if (rc < 0) {
+			if (errno == EINTR)
+				continue;
+			perror("select");
+			exit(1);
+		}
+		if (FD_ISSET(udp_fd, &fds)) {
+			recv(udp_fd, dummybuf, sizeof dummybuf, 0);
+			rx_count++;
+		} else {
+			printf("Received %u packet%s\n", rx_count,
+				rx_count != 1 ? "s" : "");
+			rx_count = 0;
+		}
+	}
+}