test-socket-signal: add receiver code
authorRazvan Deaconescu <razvan.deaconescu@cs.pub.ro>
Thu, 11 Nov 2010 14:52:24 +0000 (16:52 +0200)
committerRazvan Deaconescu <razvan.deaconescu@cs.pub.ro>
Thu, 11 Nov 2010 14:52:24 +0000 (16:52 +0200)
Utils/test-socket-signal/receiver.c [new file with mode: 0644]

diff --git a/Utils/test-socket-signal/receiver.c b/Utils/test-socket-signal/receiver.c
new file mode 100644 (file)
index 0000000..dcce1e6
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * inet (BSD) socket receiver application
+ *       starts a listener socket that receives data from requesting
+ *       client
+ *
+ * 2010, Razvan Deaconescu
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <time.h>
+#include <getopt.h>
+
+#include "sock_util.h"
+#include "utils.h"
+
+
+#define DEFAULT_LISTEN_PORT            54321
+#define DEFAULT_SERVER_BACKLOG         5
+#define DEFAULT_BUFFER_SIZE            1024
+
+#define PACKET_INDEX_SIZE              sizeof(unsigned long long)
+#define PACKET_TIMESPEC_SIZE           sizeof(time_t)
+#define PACKET_PAYLOAD_SIZE            (PACKET_SIZE - PACKET_INDEX_SIZE - PACKET_TIMESPEC_SIZE)
+#define PACKET_SIZE                    (cmd_args.buffer_size)
+
+/*
+ * TODO: fix nomenclature (TIMER_BASE_PERIOD, cmd_args.frequency)
+ * run the timer once each TIMER_BASE_PERIOD
+ * this is divided by cmd_args.frequency for a shorter period
+ */
+
+static struct {
+       unsigned short int listen_port;
+       size_t buffer_size;
+} cmd_args = {
+       .listen_port = DEFAULT_LISTEN_PORT,
+       .buffer_size = DEFAULT_BUFFER_SIZE,
+};
+
+static char *rcv_buf;
+static char *snd_buf;
+
+/* connection socket */
+static int connectfd;
+
+static void init_buffer_random(char *buf, size_t len)
+{
+       size_t i;
+
+       srand(time(NULL));
+
+       for (i = 0; i < len-2; i++)
+               buf[i] = (char) (rand() % 26) + 'a';
+       buf[i] = '\0';
+}
+
+static void init_buffers(void)
+{
+       init_buffer_random(rcv_buf, PACKET_SIZE);
+       init_buffer_random(snd_buf, PACKET_SIZE);
+}
+
+static void init(void)
+{
+       rcv_buf = malloc(PACKET_SIZE * sizeof(char));
+       snd_buf = malloc(PACKET_SIZE * sizeof(char));
+       DIE(snd_buf == NULL, "malloc");
+
+       init_buffers();
+}
+
+static void cleanup(void)
+{
+       free(rcv_buf);
+       free(snd_buf);
+}
+
+static void fill_send_buffer(void)
+{
+       static unsigned long long index = 0;
+       char *ptr;
+       time_t curr_time_secs;
+
+       curr_time_secs = time(NULL);
+
+       ptr = snd_buf + PACKET_PAYLOAD_SIZE;
+       * (unsigned long long *) ptr = index;
+       ptr += PACKET_INDEX_SIZE;
+       * (time_t *) ptr = curr_time_secs;
+
+       printf("[send] index: %llu curr_time_secs: %lu\n", index, curr_time_secs);
+       index++;
+}
+
+static ssize_t send_buffer(int sockfd)
+{
+       return send(sockfd, snd_buf, PACKET_SIZE, 0);
+}
+
+static ssize_t receive_buffer(int sockfd)
+{
+       ssize_t nbytes = 0;
+       ssize_t n;
+
+       while (nbytes < (ssize_t) PACKET_SIZE) {
+               n = recv(sockfd, rcv_buf, PACKET_SIZE - nbytes, 0);
+               if (n <= 0)
+                       break;
+               nbytes += n;
+       }
+
+       return nbytes;
+}
+
+static void print_buffer_meta(const char *buf, size_t len)
+{
+       unsigned long long index;
+       time_t curr_time_secs;
+       time_t sender_time_secs;
+       const char *ptr;
+
+       curr_time_secs = time(NULL);
+
+       ptr = buf + len - PACKET_INDEX_SIZE - PACKET_TIMESPEC_SIZE;
+       index = * (unsigned long long *) ptr;
+       ptr += PACKET_INDEX_SIZE;
+       sender_time_secs = * (time_t *) ptr;
+
+       printf("[recv] index %llu, ", index);
+       if (sender_time_secs > curr_time_secs)
+               printf("negative latency (weird)\n");
+       else
+               printf("latency %lu seconds (curr_time = %lu, sender_time = %lu)\n",
+                               curr_time_secs - sender_time_secs,
+                               curr_time_secs,
+                               sender_time_secs);
+}
+
+static void usage(const char *argv0)
+{
+       fprintf(stderr, "Usage: %s [-p | --port <listen-port>] [-b | --buffer-size <buffer-size>]\n", argv0);
+}
+
+static void print_args(void)
+{
+       printf("listen_port: %hu\n", cmd_args.listen_port);
+       printf("buffer_size: %lu\n", cmd_args.buffer_size);
+}
+
+static void parse_args(int argc, char **argv)
+{
+       int c;
+
+       while (1) {
+               int option_index = 0;
+               static struct option long_options[] = {
+                       {"port", 1, NULL, 0},
+                       {"buffer-size", 1, NULL, 0},
+                       {0, 0, 0, 0}
+               };
+
+               c = getopt_long(argc, argv, "p:b:",
+                               long_options, &option_index);
+               if (c == -1)
+                       break;
+
+               switch (c) {
+               case 0:
+                       printf("option %s", long_options[option_index].name);
+                       if (optarg)
+                               printf(" with arg %s", optarg);
+                       printf("\n");
+                       break;
+
+               case 'p':
+                       /* TODO: use strtoul */
+                       cmd_args.listen_port = atoi(optarg);
+                       break;
+
+               case 'b':
+                       /* TODO: use strtoul */
+                       cmd_args.buffer_size = atoi(optarg);
+                       break;
+
+               case '?':
+                       break;
+
+               default:
+                       printf("?? getopt returned character code 0%o ??\n", c);
+               }
+       }
+
+       if (optind != argc) {
+               usage(argv[0]);
+               exit(EXIT_FAILURE);
+       }
+
+       print_args();
+}
+
+int main(int argc, char **argv)
+{
+       int listenfd;
+       int sockfd;
+       struct sockaddr_in addr;
+       socklen_t addrlen = 0;
+
+       parse_args(argc, argv);
+
+       listenfd = tcp_listen_connections(cmd_args.listen_port,
+                       DEFAULT_SERVER_BACKLOG);
+       DIE(listenfd < 0, "tcp_listen_connections");
+
+       sockfd = accept(listenfd, (SSA *) &addr, &addrlen);
+       DIE(sockfd < 0, "accept");
+
+       while (1) {
+               ssize_t nbytes;
+
+               nbytes = receive_buffer(sockfd);
+               DIE(nbytes < 0, "receive_buffer");
+               if (nbytes == 0)
+                       break;
+
+               print_buffer_meta(rcv_buf, PACKET_SIZE);
+       }
+
+       close(sockfd);
+       close(listenfd);
+
+       return 0;
+}