diff options
Diffstat (limited to 'clip')
-rw-r--r-- | clip/Makefile | 6 | ||||
-rw-r--r-- | clip/clip.c | 125 |
2 files changed, 131 insertions, 0 deletions
diff --git a/clip/Makefile b/clip/Makefile new file mode 100644 index 0000000..426a721 --- /dev/null +++ b/clip/Makefile @@ -0,0 +1,6 @@ + +build: + gcc -Wall -Wextra -Wpedantic --std=gnu99 clip.c -o clip + +lint: + splint clip.c diff --git a/clip/clip.c b/clip/clip.c new file mode 100644 index 0000000..19e785d --- /dev/null +++ b/clip/clip.c @@ -0,0 +1,125 @@ +#include <arpa/inet.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <time.h> +#include <unistd.h> +#include <errno.h> + +#define BUFF_SIZE 1024 +#define ONE_SECOND_IN_NANOSECONDS 1000000000 + +static long int calulate_difference(struct timespec a, struct timespec b); + +int +main() { + int server_fd, new_socket; + struct sockaddr_in address; + int opt = 1; + int port = 8888; + int addrlen = sizeof(address); + char *buffer; + + // Create socket + if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) + { + perror("Could not create socket"); + exit(EXIT_FAILURE); + } + + // Set socket options + if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, + &opt, sizeof(opt))) + { + perror("Error during setsockopt"); + exit(EXIT_FAILURE); + } + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons( port ); + + //Bind + if(bind(server_fd,(struct sockaddr *)&address , sizeof(address)) < 0) + { + perror("Bind failure"); + exit(EXIT_FAILURE); + } + + if (listen(server_fd, 20) < 0) + { + perror("Listen failure"); + exit(EXIT_FAILURE); + } + + + while (1) { + new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen); + + if (new_socket < 0) { + perror("accept"); + exit(EXIT_FAILURE); + } + + // Set the socket to non blocking + fcntl(new_socket, F_SETFL, O_NONBLOCK); + + buffer = malloc(sizeof(char) * BUFF_SIZE); + + /* int res = 0; */ + int count = 0; + int idx = 0; + int size_recv = 0; + long int timeout = ONE_SECOND_IN_NANOSECONDS / 10; + struct timespec begin; + struct timespec now; + long int timediff; + char chunk[BUFF_SIZE]; + + clock_gettime(CLOCK_MONOTONIC, &begin); + + while (1) { + clock_gettime(CLOCK_MONOTONIC, &now); + + timediff = calulate_difference(now, begin); + + //if you got some data, then break after timeout + if( count > 0 && timediff > timeout ) + { + break; + } + + memset(chunk, 0, BUFF_SIZE); //clear the variable + size_recv = recv(new_socket, chunk, BUFF_SIZE, 0); + + + if (size_recv > 0) + { + buffer = realloc(buffer, (idx + BUFF_SIZE) * sizeof(char)); + memcpy((char *)buffer + idx, chunk, BUFF_SIZE); + clock_gettime(CLOCK_MONOTONIC, &begin); + } + else if (errno != EWOULDBLOCK) + { + usleep(ONE_SECOND_IN_NANOSECONDS / 10000000); + } + + count++; + idx = count * BUFF_SIZE; + } + + printf("%s\n", buffer); + close(new_socket); + free(buffer); + } + + return 0; +} + +static long int +calulate_difference(struct timespec a, struct timespec b) { + int seconds_to_nanoseconds = (a.tv_sec - b.tv_sec) * 1000000000; + return seconds_to_nanoseconds + a.tv_nsec - b.tv_nsec; +} + |