From: Razvan Deaconescu Date: Thu, 11 Nov 2010 14:52:24 +0000 (+0200) Subject: test-socket-signal: add receiver code X-Git-Url: http://p2p-next.cs.pub.ro/gitweb/?a=commitdiff_plain;h=a666e9122cb479db5a85fd4f63cb7ce620fa71b0;p=p2p-testing-infrastructure.git test-socket-signal: add receiver code --- diff --git a/Utils/test-socket-signal/receiver.c b/Utils/test-socket-signal/receiver.c new file mode 100644 index 0000000..dcce1e6 --- /dev/null +++ b/Utils/test-socket-signal/receiver.c @@ -0,0 +1,237 @@ +/* + * inet (BSD) socket receiver application + * starts a listener socket that receives data from requesting + * client + * + * 2010, Razvan Deaconescu + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 ] [-b | --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; +}