Advertisement
Guest User

Untitled

a guest
Feb 19th, 2019
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 17.57 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <sys/wait.h>
  5. #include <unistd.h>
  6. #include <ctype.h>
  7. #include <netdb.h>
  8. #include <sys/socket.h>
  9. #include <netinet/in.h>
  10. #include <time.h>
  11. #include <string.h>
  12. #include <fcntl.h>
  13. #include <sys/stat.h>
  14. #include <poll.h>
  15. #include "queue.c"
  16. #include <errno.h>
  17. #include <arpa/inet.h>
  18. #include <signal.h>
  19. #include <openssl/md5.h>
  20.  
  21.  
  22. #define sizeOfArray 1024*1024*5/4
  23. #define KB112 112*1024
  24. #define DataProduced 640
  25. #define MAX_CLIENTS 100
  26.  
  27. /* ------------------DEKLARACJE ZMIENNYCH------------------ */
  28.  
  29. //do uzupelniania magazynu
  30. int hex;                             /* Znak ASCII  */
  31. int char_number = 0;                 /* Pomocnicza zmienna */
  32.  
  33. //do raportow
  34. int currentClients=0;                /* Aktualna liczba polaczonych klientow */
  35. int sendSize=0;                      /* Liczba wyslanego materialu */
  36. int generatedSize=0;                 /* Liczba wygenerowanego materialu */
  37. int blockCounter[MAX_CLIENTS];       /* Ilosc blokow przeslanych do danego klienta */
  38. char *path = NULL;                   /* Sciezka do pliku */
  39.  
  40. //reszta
  41. Queue *pHead;                        /* Kolejeczka */
  42. Queue *ClientsQueue;
  43.  
  44. FILE *raport;                        /* Plik z raportem */
  45. fd_set readfds;
  46. struct sockaddr_in address;
  47. struct timespec monotonic, realtime; /* Znacznik TS */
  48.  
  49. //wiadomosc od konsumera
  50. char msg[6];
  51.  
  52. /* ------------------DEKLARACJE FUNKCJI------------------ */
  53.  
  54. void ReadingParameters(int argc, char** argv, float* tempo, char** path, unsigned int* port, char** addressip);
  55. void ProduceAndStore(int hex, Queue *pHead, fd_set *readfds);
  56. int PortAndAddress(unsigned int *port, char ** addressip, char *opt);
  57. void Timers(float tempo);
  58. void CreatingSocket(int *sock, char** addressip, unsigned int *port, int* addrlen);
  59. void SelectFunction(int *sock, int *max_socket_descriptor, int* socket_descriptor, int* client_socket, int * clients, fd_set* readfds);
  60. void Handler(int sig, siginfo_t *info, void *context);
  61. void RaportAboutConnetions(fd_set* readfds);
  62. void RaportAboutDisconnetions(int socket_descriptor, fd_set* readfds);
  63. void SendingBlocks(int* socket_descriptor, int* sock, fd_set* readfds);
  64.  
  65. MD5_CTX c;
  66. unsigned char out[MD5_DIGEST_LENGTH];
  67. ssize_t bytes;
  68. /*------------------------------------------------------------------------------*/
  69. /*------------------------------------------------------------------------------*/
  70.  
  71. int main(int argc, char** argv) {
  72.     /* ------------------DEKLARACJE ZMIENNYCH------------------ */
  73.  
  74.     //do wczytania parametrow
  75.     float tempo;                     /* Tempo produkcji danych */
  76.     unsigned int port = 0;           /* Port */
  77.     char *addressip = "127.0.0.1";   /* Adress */
  78.  
  79.     //do socketow
  80.     int sock;                        /* Glowny socket */
  81.     int clients = MAX_CLIENTS;       /* Maksymalna liczba clientow */
  82.     int client_socket[MAX_CLIENTS];  /* Tablica z klientami */
  83.     int addrlen;
  84.     int new_sock;
  85.  
  86.     //do ustawiania deskryptorow
  87.     int max_socket_descriptor;
  88.     int socket_descriptor;
  89.  
  90.     //do selecta
  91.     int valread;            /* Pomocnicze do obslugi polaczenia */
  92.  
  93.     /* -------------------------------------------------------- */
  94.     if(argc < 4) {
  95.         printf("Brakuje parametrow!\n");
  96.         printf("Prosze podać parametry w ten sposób: -r<sciezka> -t<val> [<addr>]:port\n");
  97.         exit(1);
  98.     }
  99.  
  100.     bzero(blockCounter, MAX_CLIENTS);
  101.  
  102.     pHead = createQueue(sizeOfArray);                  /* 1) a INICJALIZACJA KOLEJKI Z DANYMI */
  103.     ClientsQueue = createQueueClients(MAX_CLIENTS);    /* 1) b INICJALIZACJA KOLEJKI Z KLIENTAMI*/
  104.  
  105.     ReadingParameters(argc, argv, &tempo, &path, &port, &addressip);      /* 2) WCZYTANIE PARAMETROW */
  106.  
  107.     Timers(tempo);                                                       /* 3) TWORZENIE ORAZ OBSLUGA TIMEROW */
  108.  
  109.     for (int i = 0; i < clients; i++) {
  110.         client_socket[i] = 0;
  111.     }
  112.  
  113.     /* 4) TWORZENIE ORAZ OBSLUGA SOCKETU */
  114.  
  115.     CreatingSocket(&sock, &addressip, &port, &addrlen);
  116.  
  117.     raport = fopen(path, "w+");
  118.     if (!raport)
  119.         perror( "Error open file\n");
  120.  
  121.     while (1) {
  122.  
  123.         FD_ZERO(&readfds);
  124.         FD_SET(sock, &readfds);
  125.  
  126.         /* 5) USTAWIANIE DESKRYPTORA ORAZ SELECTA*/
  127.         SelectFunction(&sock, &max_socket_descriptor, &socket_descriptor, client_socket, &clients, &readfds);
  128.  
  129.  
  130.         if (FD_ISSET(sock, &readfds)) {
  131.             if ((new_sock = accept(sock, (struct sockaddr *) &address, (socklen_t * ) & addrlen)) < 0) {
  132.                 perror("accept error");
  133.                 exit(1);
  134.             }
  135.             RaportAboutConnetions(&readfds);      /* 7) - a  POLACZENIA */
  136.  
  137.             /* 8) DODANIE DO LISTY KLIENTOW */
  138.             for (int i = 0; i < clients; i++) {
  139.                 if (client_socket[i] == 0) {
  140.                     client_socket[i] = new_sock;
  141.                     break;
  142.                 }
  143.             }
  144.         }
  145.         for (int i = 0; i < clients; i++) {
  146.             socket_descriptor = client_socket[i];
  147.  
  148.             if (FD_ISSET(socket_descriptor, &readfds)) {
  149.  
  150.                 /* 9) a ROZLACZENIE JEZELI VALREAD ROWNY 0 */
  151.  
  152.                 if ((valread = read(socket_descriptor, msg, 6)) == 0) {
  153.  
  154.                     getpeername(socket_descriptor, (struct sockaddr *) &address, (socklen_t * ) & addrlen);
  155.  
  156.                     RaportAboutDisconnetions(socket_descriptor, &readfds);    /* 7) - b  ROZLACZENIA */
  157.  
  158.                     blockCounter[socket_descriptor]=0;
  159.                     close(socket_descriptor);
  160.                     client_socket[i] = 0;
  161.                 }
  162.                 else {
  163.                     pushClients(ClientsQueue, socket_descriptor);
  164.                 }
  165.             }
  166.         }
  167.         if(size(ClientsQueue) > 0)
  168.         {
  169.             SendingBlocks(&socket_descriptor, &sock, &readfds);
  170.         }
  171.     }
  172. }
  173.  
  174. /*------------------------------------------------------------------------------*/
  175.  
  176. void ReadingParameters(int argc, char** argv, float* tempo, char** path, unsigned int* port, char** addressip)
  177. {
  178.     int c;
  179.     char *ptr;
  180.     char *val = NULL;
  181.     int rflag = 0;
  182.     int tflag = 0;
  183.  
  184.     for (int i = optind; i < argc; i++) {
  185.         if ((c = getopt(argc, argv, "r:t:")) != -1) {
  186.             switch (c) {
  187.                 case 'r':
  188.                     rflag=1;
  189.                     //printf("option -r with value %s\n", optarg);
  190.                     *path = optarg;
  191.  
  192.                     break;
  193.                 case 't':
  194.                     tflag=1;
  195.                     //printf("option -t with value %s\n", optarg);
  196.                     val = optarg;
  197.                     *tempo = strtof(val, &ptr);
  198.                     if (*tempo < 1 || *tempo > 8) {
  199.                         printf("Tempo powinno być w przedziale od 1 do 8.\n");
  200.                         exit(1);
  201.                     }
  202.                     *tempo = *tempo * 60 / 96/500;
  203.                     //printf("%f\n",*tempo);
  204.  
  205.                     break;
  206.                 default:
  207.                     printf("ERROR: Parametr needs an argument!\n");
  208.                     exit(1);
  209.                     break;
  210.             }
  211.         }
  212.     }
  213.     if(PortAndAddress(port, addressip, argv[optind])== 0){
  214.         printf("Nie udalo sie utworzyc portu i adresu");
  215.         exit(1);
  216.     }
  217.     if(!(rflag && tflag)){
  218.         printf("Brakuje jednej z flag!\n");
  219.         exit(EXIT_FAILURE);
  220.     }
  221. }
  222.  
  223. /*------------------------------------------------------------------------------*/
  224.  
  225. int PortAndAddress(unsigned int *port, char** addressip, char* opt)
  226. {
  227.     char *tmp = NULL;
  228.     char *pch;
  229.     char colon = ':';
  230.  
  231.     struct hostent *host;
  232.     struct in_addr **addr_list;
  233.  
  234.     if((tmp=opt) == 0)
  235.     {
  236.         printf("Nieprawidłowy parametr\n");
  237.         exit(1);
  238.     }
  239.     *port = strtol(tmp, NULL, 0);
  240.  
  241.     for(int i = 0; i < strlen(tmp); i++)
  242.     {
  243.         if(tmp[i] == colon)
  244.         {
  245.             pch = strtok(tmp, ":");
  246.             *addressip = pch;
  247.  
  248.             pch = strtok(NULL, ":");
  249.             *port = strtol(pch, NULL, 0);
  250.         }
  251.     }
  252.     if( *port < 1024) {
  253.         printf("Nieprawidłowy port!\n");
  254.         exit(1);
  255.     }
  256.     if (!(host = gethostbyname(*addressip))){
  257.         perror("Gethostbyname error");
  258.         exit(EXIT_FAILURE);
  259.     }
  260.     addr_list = (struct in_addr **) host->h_addr_list;
  261.  
  262.     int q = 0;
  263.     if( !addr_list[q] ) {
  264.         printf("Podaj poprawny adres!\n");
  265.         exit(1);
  266.     }
  267.     *addressip = inet_ntoa(*addr_list[q]);
  268.  
  269.     return 1;
  270. }
  271.  
  272. /*------------------------------------------------------------------------------*/
  273.  
  274. void ProduceAndStore(int hex, Queue *pHead, fd_set *readfds) {
  275.     char *tmp = (char *)malloc(sizeof(char)*640);
  276.     if(size(pHead)*DataProduced+DataProduced<=pHead->capacity) {
  277.         memset(tmp, hex, 640);
  278.         push(pHead, tmp);
  279.     }
  280.     generatedSize++;
  281. }
  282.  
  283. /*------------------------------------------------------------------------------*/
  284.  
  285. void Timers(float tempo) {
  286.     timer_t timer;
  287.     timer_t timer2;
  288.     struct sigaction sa;
  289.     sigemptyset(&sa.sa_mask);
  290.     sigaddset(&sa.sa_mask, SIGINT);
  291.     struct sigevent sev;
  292.     struct sigevent sev2;
  293.     struct itimerspec its;
  294.     struct itimerspec its2;
  295.  
  296.     sa.sa_flags = SA_SIGINFO;
  297.     sa.sa_sigaction = Handler;
  298.  
  299.     if (sigaction(SIGRTMIN, &sa, NULL) == -1) {
  300.         perror("SIGRTMIN error");
  301.     }
  302.     if (sigaction(SIGUSR1, &sa, NULL) == -1) {
  303.         perror("SIGUSR1 error");
  304.     }
  305.  
  306.     sev.sigev_notify = SIGEV_SIGNAL;
  307.     sev.sigev_signo = SIGRTMIN;
  308.     sev.sigev_value.sival_ptr = &timer;
  309.  
  310.     sev2.sigev_notify = SIGEV_SIGNAL;
  311.     sev2.sigev_signo = SIGUSR1;
  312.     sev2.sigev_value.sival_ptr = &timer2;
  313.  
  314.     if (timer_create(CLOCK_REALTIME, &sev, &timer) == -1) {
  315.         printf("create error\n");
  316.         exit(EXIT_FAILURE);
  317.     }
  318.     if (timer_create(CLOCK_REALTIME, &sev2, &timer2) == -1) {
  319.         printf("create error\n");
  320.         exit(EXIT_FAILURE);
  321.     }
  322.     its.it_value.tv_sec = tempo;
  323.     its.it_value.tv_nsec = (tempo-(int)tempo)*1000*(1000000L);
  324.     its.it_interval.tv_sec = its.it_value.tv_sec;
  325.     its.it_interval.tv_nsec = its.it_value.tv_nsec;
  326.  
  327.     its2.it_value.tv_sec = 5;
  328.     its2.it_value.tv_nsec = 0;
  329.     its2.it_interval.tv_sec = its2.it_value.tv_sec;
  330.     its2.it_interval.tv_nsec = its2.it_value.tv_nsec;
  331.  
  332.     if (timer_settime(timer, 0, &its, NULL) == -1) {
  333.         printf("settime error\n");
  334.     }
  335.     if (timer_settime(timer2, 0, &its2, NULL) == -1) {
  336.         printf("settime error\n");
  337.     }
  338. }
  339. /*------------------------------------------------------------------------------*/
  340.  
  341. void CreatingSocket(int *sock, char** addressip, unsigned int *port, int* addrlen)
  342. {
  343.     int opt = 1;
  344.  
  345.     if ((*sock = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
  346.         perror("socket failed");
  347.         exit(1);
  348.     }
  349.  
  350.     if (setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt)) < 0) {
  351.         perror("setsockopt");
  352.         exit(1);
  353.     }
  354.     address.sin_family = AF_INET;
  355.     address.sin_addr.s_addr = inet_addr(*addressip);
  356.     address.sin_port = htons(*port);
  357.  
  358.     if (bind(*sock, (struct sockaddr *) &address, sizeof(address)) < 0) {
  359.         perror("bind failed");
  360.         exit(EXIT_FAILURE);
  361.     }
  362.  
  363.     if (listen(*sock, 3) < 0) {
  364.         perror("listen");
  365.         exit(1);
  366.     }
  367.     *addrlen = sizeof(address);
  368.     puts("Czekam na polaczenia ...");
  369.  
  370. }
  371. void SelectFunction(int *sock, int *max_socket_descriptor, int* socket_descriptor, int * client_socket, int * clients, fd_set* readfds)
  372. {
  373.     int activity;
  374.  
  375.     FD_ZERO(readfds);
  376.     FD_SET(*sock, readfds);
  377.  
  378.     /* 5) USTAWIANIE DESKRYPTORA */
  379.  
  380.     *max_socket_descriptor = *sock;
  381.  
  382.     for (int i = 0; i < *clients; i++) {
  383.  
  384.         *socket_descriptor = client_socket[i];
  385.  
  386.         if (*socket_descriptor > 0)
  387.             FD_SET(*socket_descriptor, readfds);
  388.  
  389.         if (*socket_descriptor > *max_socket_descriptor)
  390.             *max_socket_descriptor = *socket_descriptor;
  391.     }
  392.  
  393.     activity = select(*max_socket_descriptor + 1, readfds, NULL, NULL, NULL);  /* 6) OBSLUGA WIELU POLACZEN JEDNOCZESNIE */
  394.     if ((activity < 0) && (errno != EINTR)) {
  395.         printf("select error");
  396.     }
  397. }
  398.  
  399. /*------------------------------------------------------------------------------*/
  400.  
  401. void Handler(int sig, siginfo_t *info, void *context) {
  402.     FD_ZERO(&readfds);
  403.     if (sig == SIGUSR1) {
  404.         if (clock_gettime(CLOCK_MONOTONIC, &monotonic))
  405.             perror("clock monotonic error");
  406.         if (clock_gettime(CLOCK_REALTIME, &realtime))
  407.             perror("clock realtime error");
  408.  
  409.         float cap = pHead->capacity;
  410.  
  411.         float busy = size(pHead) * DataProduced / cap;
  412.         raport = fopen(path, "a");
  413.         if (!raport)
  414.             perror( "Error open file\n");
  415.         fprintf(raport, "\n------------------------RAPORT------------------------\n");
  416.         fprintf(raport, "Podlaczonych uzytkownikow: %d\n", currentClients);
  417.         fprintf(raport, "Zajetośc magazynu: %d/%d  (%f)\n", size(pHead) * DataProduced, (int) cap, busy * 100);
  418.         fprintf(raport, "Przepływ materialu w ciagu ostatnich 5 sekund: %d\n",(generatedSize*DataProduced)-sendSize );
  419.         fprintf(raport, "TS: Monotonic: %lds %ldns\tRealTime: %lds %ldns\n", monotonic.tv_sec, monotonic.tv_nsec,
  420.                 realtime.tv_sec, realtime.tv_nsec);
  421.         fprintf(raport, "------------------------------------------------------\n");
  422.         fflush(raport);
  423.         fclose(raport);
  424.         generatedSize=0;
  425.         sendSize=0;
  426.  
  427.     }
  428.     if (sig == SIGRTMIN) {
  429.  
  430.         if (char_number > 25)
  431.             hex = 65 - 26 + char_number;
  432.         else
  433.             hex = 97 + char_number;
  434.         ProduceAndStore(hex, pHead, &readfds);
  435.         char_number++;
  436.         if (char_number > 51)
  437.             char_number = 0;
  438.     }
  439. }
  440.  
  441. /*------------------------------------------------------------------------------*/
  442.  
  443. void RaportAboutConnetions(fd_set* readfds)
  444. {
  445.     FD_ZERO(readfds);
  446.     if (clock_gettime(CLOCK_MONOTONIC, &monotonic))
  447.         perror("clock monotonic error");
  448.     if (clock_gettime(CLOCK_REALTIME, &realtime))
  449.         perror("clock realtime error");
  450.  
  451.     raport = fopen(path, "a");
  452.     if (!raport)
  453.         perror( "Error open file\n");
  454.  
  455.     fprintf(raport, "\n----------------------POLACZENIA----------------------\n");
  456.     fprintf(raport, "Polaczono z nowym klientem o adresie %s!\n", inet_ntoa(address.sin_addr));
  457.     fprintf(raport, "TS: Monotonic: %lds %ldns\tRealTime: %lds %ldns\n", monotonic.tv_sec, monotonic.tv_nsec,
  458.             realtime.tv_sec, realtime.tv_nsec);
  459.     fprintf(raport, "------------------------------------------------------\n");
  460.     fflush(raport);
  461.     fclose(raport);
  462.  
  463.     currentClients++;
  464. }
  465.  
  466. /*------------------------------------------------------------------------------*/
  467.  
  468. void RaportAboutDisconnetions(int socket_descriptor, fd_set* readfds)
  469. {
  470.     FD_ZERO(readfds);
  471.     if (clock_gettime(CLOCK_MONOTONIC, &monotonic))
  472.         perror("clock monotonic error");
  473.     if (clock_gettime(CLOCK_REALTIME, &realtime))
  474.         perror("clock realtime error");
  475.  
  476.     raport = fopen(path, "a");
  477.     if (!raport)
  478.         perror( "Error open file\n");
  479.  
  480.     fprintf(raport, "\n----------------------ROZLACZENIA---------------------\n");
  481.     fprintf(raport, "Rozlaczono z klientem o adresie %s!\n", inet_ntoa(address.sin_addr));
  482.     fprintf(raport, "Ilosc wyslanych blokow z danymi: %d\n", blockCounter[socket_descriptor]);
  483.     fprintf(raport, "TS: Monotonic: %lds %ldns\tRealTime: %lds %ldns\n", monotonic.tv_sec,
  484.             monotonic.tv_nsec, realtime.tv_sec, realtime.tv_nsec);
  485.     fprintf(raport, "-------------------------------------------------------\n");
  486.     fflush(raport);
  487.     fclose(raport);
  488.  
  489.     currentClients--;
  490.  
  491. }
  492.  
  493. /*------------------------------------------------------------------------------*/
  494.  
  495. void SendingBlocks(int* socket_descriptor, int *sock, fd_set* readfds)
  496. {
  497.     FD_ZERO(readfds);
  498.  
  499.     if (size(pHead) * DataProduced  > KB112 + 640) {
  500.         char *DataBlock = (char *)malloc(sizeof(char)*114689);
  501.         bzero(DataBlock, 114689);
  502.         char *wsk = &DataBlock[0];
  503.         char *tmp = (char *)malloc(sizeof(char)*640);
  504.         bzero(tmp, 640);
  505.  
  506.         bzero(DataBlock, KB112 + 1);
  507.         for (int j = 0; j < KB112 / DataProduced; j++) {
  508.             tmp = pop(pHead);
  509.             memcpy(wsk, tmp, 640);
  510.             wsk += 640;
  511.             bzero(tmp, 641);
  512.             if(strlen(DataBlock)==114560){
  513.                 char *tmp1 = (char *)malloc(sizeof(char) * 640);
  514.                 memset(tmp1, '0', strlen(tmp1));
  515.                 tmp1 = pop(pHead);
  516.                 char *tmp2 = (char *)malloc(sizeof(char) * 128);
  517.                 memcpy(tmp2, tmp1, 128);
  518.                 memcpy(wsk, tmp1, 128);
  519.             }
  520.         }
  521.         //printf("magazyn to: %s\n", DataBlock);
  522.         int whichClient = popClients(ClientsQueue);
  523.         if ((bytes=send(whichClient, DataBlock, strlen(DataBlock), 0)) == 0) {
  524.             perror("send");
  525.             close(*sock);
  526.             exit(1);
  527.         }
  528.         //printf("Datablock: %s\n", DataBlock);
  529.         MD5_Init(&c);
  530.         MD5_Update(&c, DataBlock, 114688);
  531.         MD5_Final(out, &c);
  532.         printf("Rozmiar wyslanego bloku danych: %ld\n",bytes);
  533.         for(int i = 0; i < MD5_DIGEST_LENGTH; i++)
  534.             printf("%02x", out[i]);
  535.         printf("\n");
  536.         sendSize = sendSize + KB112;
  537.         blockCounter[whichClient]++;
  538.         free(tmp);
  539.         //free(tmp1);
  540.         //free(tmp2);
  541.         free(DataBlock);
  542.     }
  543. }
  544.  
  545. /*------------------------------------------------------------------------------*/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement