From ce12405424a3e7d5a38d842a7bf65ce02872c147 Mon Sep 17 00:00:00 2001 From: Razvan Deaconescu Date: Thu, 11 Nov 2010 16:52:32 +0200 Subject: [PATCH] test-socket-signal: add sender code --- Utils/test-socket-signal/sender.c | 218 ++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 Utils/test-socket-signal/sender.c diff --git a/Utils/test-socket-signal/sender.c b/Utils/test-socket-signal/sender.c new file mode 100644 index 0000000..7c60467 --- /dev/null +++ b/Utils/test-socket-signal/sender.c @@ -0,0 +1,218 @@ +/* + * inet (BSD) socket sender application + * starts a client socket that connects to server and sends data + * + * 2010, Razvan Deaconescu + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 ] [-d | --delay ] \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; +} -- 2.20.1