test-socket-signal: parse and integrate command line options
authorRazvan Deaconescu <razvan.deaconescu@cs.pub.ro>
Sun, 24 Oct 2010 09:03:31 +0000 (12:03 +0300)
committerRazvan Deaconescu <razvan.deaconescu@cs.pub.ro>
Sun, 24 Oct 2010 09:23:34 +0000 (12:23 +0300)
Utils/test-socket-signal/peer.c

index 54a9041..7b4e556 100644 (file)
 #include "sock_util.h"
 #include "utils.h"
 
-#define DEFAULT_LEADER_LISTEN_PORT     43210
-#define DEFAULT_LEADER_HOSTNAME                "localhost"
-#define DEFAULT_FOLLOWER_LISTEN_PORT   54321
-#define DEFAULT_FOLLOWER_HOSTNAME      "localhost"
 
+#define DEFAULT_LISTEN_PORT            54321
 #define DEFAULT_SERVER_BACKLOG         5
+#define DEFAULT_BUFFER_SIZE            1024
+#define DEFAULT_FREQUENCY              1
+
 
-#define PACKET_PAYLOAD_SIZE            120
 #define PACKET_INDEX_SIZE              sizeof(unsigned long long)
 #define PACKET_TIMESPEC_SIZE           sizeof(time_t)
-#define PACKET_SIZE                    (PACKET_PAYLOAD_SIZE + PACKET_INDEX_SIZE + PACKET_TIMESPEC_SIZE)
+#define PACKET_PAYLOAD_SIZE            (PACKET_SIZE - PACKET_INDEX_SIZE - PACKET_TIMESPEC_SIZE)
+#define PACKET_SIZE                    (cmd_args.buffer_size)
+
+#define RECEIVE_BUFFER_SIZE            65536
 
 #define TIMER_FREQUENCY_SECS           1
 #define CLOCKID                                CLOCK_REALTIME
 #define SIG                            SIGRTMIN
 
-static enum {
-       TYPE_LEADER = 1,
-       TYPE_FOLLOWER,
-       TYPE_OLD_LEADER
-} client_type;
-
 
-static char rcv_buf[PACKET_SIZE];
-static char snd_buf[PACKET_SIZE];
+static struct {
+       enum {
+               TYPE_LEADER = 1,
+               TYPE_FOLLOWER,
+       } client_type;
+       unsigned short int listen_port;
+       size_t buffer_size;
+       size_t peer_buffer_size;
+       size_t frequency;
+       char remote_host[128];
+       unsigned short int remote_port;
+} cmd_args = {
+       .client_type = TYPE_FOLLOWER,
+       .listen_port = DEFAULT_LISTEN_PORT,
+       .buffer_size = DEFAULT_BUFFER_SIZE,
+       .peer_buffer_size = DEFAULT_BUFFER_SIZE,
+       .frequency = DEFAULT_FREQUENCY
+};
+
+static char rcv_buf[RECEIVE_BUFFER_SIZE];
+static char *snd_buf;
 
 /* connection socket */
 static int connectfd;
@@ -63,10 +78,23 @@ static void init_buffer_random(char *buf, size_t len)
 
 static void init_buffers(void)
 {
-       init_buffer_random(rcv_buf, PACKET_PAYLOAD_SIZE);
+       init_buffer_random(rcv_buf, RECEIVE_BUFFER_SIZE);
        init_buffer_random(snd_buf, PACKET_PAYLOAD_SIZE);
 }
 
+static void init(void)
+{
+       snd_buf = malloc(PACKET_SIZE * sizeof(char));
+       DIE(snd_buf == NULL, "malloc");
+
+       init_buffers();
+}
+
+static void cleanup(void)
+{
+       free(snd_buf);
+}
+
 static void fill_send_buffer(void)
 {
        static unsigned long long index = 0;
@@ -91,7 +119,17 @@ static ssize_t send_buffer(int sockfd)
 
 static ssize_t receive_buffer(int sockfd)
 {
-       return recv(sockfd, rcv_buf, PACKET_SIZE, 0);
+       ssize_t nbytes = 0;
+       ssize_t n;
+
+       while (nbytes < (ssize_t) cmd_args.peer_buffer_size) {
+               n = recv(sockfd, rcv_buf, RECEIVE_BUFFER_SIZE, 0);
+               if (n <= 0)
+                       break;
+               nbytes += n;
+       }
+
+       return nbytes;
 }
 
 static void timer_handler(int sig, siginfo_t *si, void *uc)
@@ -150,7 +188,7 @@ static void schedule_timer(void)
        DIE(rc < 0, "sigprocmask");
 }
 
-static void print_buffer_meta(void)
+static void print_buffer_meta(const char *buf, size_t len)
 {
        unsigned long long index;
        time_t curr_time_secs;
@@ -159,7 +197,7 @@ static void print_buffer_meta(void)
 
        curr_time_secs = time(NULL);
 
-       ptr = rcv_buf + PACKET_PAYLOAD_SIZE;
+       ptr = rcv_buf + len - PACKET_INDEX_SIZE - PACKET_TIMESPEC_SIZE;
        index = * (unsigned long long *) ptr;
        ptr += PACKET_INDEX_SIZE;
        sender_time_secs = * (time_t *) ptr;
@@ -174,28 +212,52 @@ static void print_buffer_meta(void)
                                sender_time_secs);
 }
 
+/* TODO: fill usage */
+
 static void usage(const char *argv0)
 {
-       fprintf(stderr, "Usage: %s [-l | --leader] [-p | --port <listen-port>] [-b | --buffer-size <buffer-size>] [-f | --frequency <frequency>] <peer-host> <peer-port>\n", argv0);
+       fprintf(stderr, "Usage: %s [-l | --leader] [-p | --port <listen-port>] [-b | --buffer-size <buffer-size>] [-e | --peer_buffer_size <buffer-size>] [-f | --frequency <frequency>] <peer-host> <peer-port>\n", argv0);
+}
+
+static void print_args(void)
+{
+       printf("client_type: ");
+       switch (cmd_args.client_type) {
+       case TYPE_LEADER:
+               printf("leader");
+               break;
+       case TYPE_FOLLOWER:
+               printf("follower");
+               break;
+       default:
+               printf("unknown");
+       }
+       printf("\n");
+
+       printf("listen_port: %hu\n", cmd_args.listen_port);
+       printf("buffer_size: %lu\n", cmd_args.buffer_size);
+       printf("peer_buffer_size: %lu\n", cmd_args.peer_buffer_size);
+       printf("frequency: %lu\n", cmd_args.frequency);
+       printf("remote_host: %s\n", cmd_args.remote_host);
+       printf("remote_port: %hu\n", cmd_args.remote_port);
 }
 
 static void parse_args(int argc, char **argv)
 {
        int c;
-       int digit_optind = 0;
 
        while (1) {
-               int this_option_optind = optind ? optind : 1;
                int option_index = 0;
                static struct option long_options[] = {
                        {"leader", 0, NULL, 0},
                        {"port", 1, NULL, 0},
                        {"buffer-size", 1, NULL, 0},
+                       {"peer-buffer-size", 1, NULL, 0},
                        {"frequency", 1, NULL, 0},
                        {0, 0, 0, 0}
                };
 
-               c = getopt_long(argc, argv, "lp:b:f:",
+               c = getopt_long(argc, argv, "lp:b:e:f:",
                                long_options, &option_index);
                if (c == -1)
                        break;
@@ -209,19 +271,27 @@ static void parse_args(int argc, char **argv)
                        break;
 
                case 'l':
-                       printf("option l\n");
+                       cmd_args.client_type = TYPE_LEADER;
                        break;
 
                case 'p':
-                       printf("option l with value '%s'\n", optarg);
+                       /* TODO: use strtoul */
+                       cmd_args.listen_port = atoi(optarg);
                        break;
 
                case 'b':
-                       printf("option b with value '%s'\n", optarg);
+                       /* TODO: use strtoul */
+                       cmd_args.buffer_size = atoi(optarg);
+                       break;
+
+               case 'e':
+                       /* TODO: use strtoul */
+                       cmd_args.peer_buffer_size = atoi(optarg);
                        break;
 
                case 'f':
-                       printf("option f with value '%s'\n", optarg);
+                       /* TODO: use strtoul */
+                       cmd_args.frequency = atoi(optarg);
                        break;
 
                case '?':
@@ -232,12 +302,17 @@ static void parse_args(int argc, char **argv)
                }
        }
 
-       if (optind < argc) {
-               printf("non-option ARGV-elements: ");
-               while (optind < argc)
-                       printf("%s ", argv[optind++]);
-               printf("\n");
+       if (optind + 2 != argc) {
+               usage(argv[0]);
+               exit(EXIT_FAILURE);
        }
+
+       /* TODO: check argv[argc-2] size */
+       strcpy(cmd_args.remote_host, argv[argc-2]);
+       /* TODO: use strtoul */
+       cmd_args.remote_port = atoi(argv[argc-1]);
+
+       print_args();
 }
 
 int main(int argc, char **argv)
@@ -249,49 +324,39 @@ int main(int argc, char **argv)
 
        parse_args(argc, argv);
 
-#if 0
-       if (client_type == TYPE_LEADER) {
-               listenfd = tcp_listen_connections(DEFAULT_LEADER_LISTEN_PORT,
+       switch (cmd_args.client_type) {
+       case TYPE_LEADER:
+               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");
 
-               connectfd = tcp_connect_to_server(DEFAULT_FOLLOWER_HOSTNAME,
-                               DEFAULT_FOLLOWER_LISTEN_PORT);
-               DIE(connectfd < 0, "tcp_connect_to_server");
-       }
-       else if (client_type == TYPE_FOLLOWER) {
-               listenfd = tcp_listen_connections(DEFAULT_FOLLOWER_LISTEN_PORT,
-                               DEFAULT_SERVER_BACKLOG);
-               DIE(listenfd < 0, "tcp_listen_connections");
-
-               connectfd = tcp_connect_to_server(DEFAULT_LEADER_HOSTNAME,
-                               DEFAULT_LEADER_LISTEN_PORT);
+               connectfd = tcp_connect_to_server(cmd_args.remote_host,
+                               cmd_args.remote_port);
                DIE(connectfd < 0, "tcp_connect_to_server");
+               break;
 
-               sockfd = accept(listenfd, (SSA *) &addr, &addrlen);
-               DIE(sockfd < 0, "accept");
-       }
-       else if (client_type == TYPE_OLD_LEADER) {
-               listenfd = tcp_listen_connections(DEFAULT_LEADER_LISTEN_PORT,
+       case TYPE_FOLLOWER:
+               listenfd = tcp_listen_connections(cmd_args.listen_port,
                                DEFAULT_SERVER_BACKLOG);
                DIE(listenfd < 0, "tcp_listen_connections");
 
-               connectfd = tcp_connect_to_server(DEFAULT_FOLLOWER_HOSTNAME,
-                               DEFAULT_FOLLOWER_LISTEN_PORT);
+               connectfd = tcp_connect_to_server(cmd_args.remote_host,
+                               cmd_args.remote_port);
                DIE(connectfd < 0, "tcp_connect_to_server");
 
                sockfd = accept(listenfd, (SSA *) &addr, &addrlen);
                DIE(sockfd < 0, "accept");
-       }
-       else {
+               break;
+
+       default:
                usage(argv[0]);
                exit(EXIT_FAILURE);
        }
 
-       init_buffers();
+       init();
        schedule_timer();
 
        while (1) {
@@ -305,25 +370,19 @@ int main(int argc, char **argv)
 
                        sockfd = accept(listenfd, (SSA *) &addr, &addrlen);
                        DIE(sockfd < 0, "accept");
+                       connectfd = tcp_connect_to_server(cmd_args.remote_host, cmd_args.remote_port);
+                       DIE(connectfd < 0, "tcp_connect_to_server");
 
-                       if (client_type == TYPE_FOLLOWER) {
-                               connectfd = tcp_connect_to_server(DEFAULT_LEADER_HOSTNAME, DEFAULT_LEADER_LISTEN_PORT);
-                               DIE(connectfd < 0, "tcp_connect_to_server");
-                       }
-                       if (client_type == TYPE_LEADER || client_type == TYPE_OLD_LEADER) {
-                               connectfd = tcp_connect_to_server(DEFAULT_FOLLOWER_HOSTNAME, DEFAULT_FOLLOWER_LISTEN_PORT);
-                               DIE(connectfd < 0, "tcp_connect_to_server");
-                       }
                        schedule_timer();
                }
 
-               print_buffer_meta();
+               print_buffer_meta(rcv_buf, nbytes);
        }
 
        close(sockfd);
        close(connectfd);
 
-#endif
+       cleanup();
 
        return 0;
 }