summaryrefslogtreecommitdiff
path: root/clip/clip.c
blob: 19e785d802753843dd8d24db0f2931a17462f327 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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;
}