Advertisement
Guest User

Untitled

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