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

diff --git a/Utils/test-socket-signal/sender.c b/Utils/test-socket-signal/sender.c
new file mode 100644 (file)
index 0000000..7c60467
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * inet (BSD) socket sender application
+ *       starts a client socket that connects to server and sends data
+ *
+ * 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_BUFFER_SIZE            1024
+#define DEFAULT_PACKET_DELAY           1000
+
+#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)
+
+
+static struct {
+       size_t buffer_size;
+       size_t packet_delay;    /* milliseconds */
+       char server_host[128];
+       unsigned short int server_port;
+} cmd_args = {
+       .buffer_size = DEFAULT_BUFFER_SIZE,
+       .packet_delay = DEFAULT_PACKET_DELAY,
+};
+
+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_PAYLOAD_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 delay_packet(void)
+{
+       struct timespec ts;
+       int rc;
+
+       ts.tv_sec = cmd_args.packet_delay / 1000;
+       ts.tv_nsec = (cmd_args.packet_delay % 1000) * 1000000;
+
+       rc = nanosleep(&ts, NULL);
+       DIE(rc < 0, "nanosleep");
+}
+
+static void usage(const char *argv0)
+{
+       fprintf(stderr, "Usage: %s [-b | --buffer-size <buffer-size>] [-d | --delay <packet-delay>] <server-host> <server-port>\n", argv0);
+}
+
+static void print_args(void)
+{
+       printf("buffer_size: %lu\n", cmd_args.buffer_size);
+       printf("delay: %lu\n", cmd_args.packet_delay);
+       printf("server_host: %s\n", cmd_args.server_host);
+       printf("server_port: %hu\n", cmd_args.server_port);
+}
+
+static void parse_args(int argc, char **argv)
+{
+       int c;
+
+       while (1) {
+               int option_index = 0;
+               static struct option long_options[] = {
+                       {"buffer-size", 1, NULL, 0},
+                       {"packet-delay", 1, NULL, 0},
+                       {0, 0, 0, 0}
+               };
+
+               c = getopt_long(argc, argv, "b:d:",
+                               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 'b':
+                       /* TODO: use strtoul */
+                       cmd_args.buffer_size = atoi(optarg);
+                       break;
+
+               case 'd':
+                       /* TODO: use strtoul */
+                       cmd_args.packet_delay = atoi(optarg);
+                       break;
+
+               case '?':
+                       break;
+
+               default:
+                       printf("?? getopt returned character code 0%o ??\n", c);
+               }
+       }
+
+       if (optind + 2 != argc) {
+               usage(argv[0]);
+               exit(EXIT_FAILURE);
+       }
+
+       /* TODO: check argv[argc-2] size */
+       strcpy(cmd_args.server_host, argv[argc-2]);
+       /* TODO: use strtoul */
+       cmd_args.server_port = atoi(argv[argc-1]);
+
+       print_args();
+}
+
+int main(void)
+{
+       connectfd = tcp_connect_to_server(cmd_args.server_host,
+                       cmd_args.server_port);
+       DIE(connectfd < 0, "tcp_connect_to_server");
+
+       init();
+
+       while (1) {
+               ssize_t nbytes;
+
+               fill_send_buffer();
+               nbytes = send_buffer(connectfd);
+               DIE(nbytes < 0, "send_buffer");
+               delay_packet();
+       }
+
+       close(connectfd);
+
+       cleanup();
+
+       return 0;
+}