SHARE
TWEET

Untitled

a guest Feb 16th, 2019 83 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <sys/types.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <sys/socket.h>
  5. #include <netinet/in.h>
  6. #include <string.h>
  7. #include <arpa/inet.h>
  8. #include <fcntl.h>
  9. #include <unistd.h>
  10. #include <ctype.h>
  11. #include <sys/ioctl.h>
  12. #include <sys/poll.h>
  13. #include <sys/time.h>
  14. #include <errno.h>
  15. #include <netdb.h>
  16. #include <time.h>
  17. #include <sys/timerfd.h>
  18.  
  19. void Raporting(char * buf, int raport, int count);
  20. char* CheckingParameters(int argc, char*argv[], int* t, char* adres, long* port);
  21. void nano(float od_czas);
  22. void error(char* fun, int fd);
  23. int CheckingRcv(int rc, int * clCon);
  24. char makeBuffer(int * data_size, char cc, char buf[], char* send_buf );
  25. void GettingTime( int raport);
  26. char Add_to_Buffer(int * data_size, char cc, char buf[], int* il_mat);
  27. int Take_from_Buffer(int * data_size, char buf[], char * send_buf);
  28. void Raport3(int raport, int data_size, int *il_mat, int *il_wydan, int nfds);
  29. void Raport2( int * il_blocks, int raport, char * adrIp);
  30.  
  31.  
  32. //      BUFOR
  33.  
  34.  
  35. #define BUFSIZE 200      // rozmiar bufora
  36. #define GIVESIZE 3         // rozmiar bloku do wypelniania
  37. #define SENDSIZE 180      // rozmiar pobieranych danych
  38.  
  39. char buf[BUFSIZE];
  40. char *pIn, *pOut, *pEnd;
  41. char full;
  42.  
  43. void buf_init()
  44. {
  45.    pIn = pOut = buf;
  46.    pEnd = &buf[BUFSIZE];
  47.    full = 0;
  48. }
  49.  
  50. int buf_put(char c)
  51. {
  52.    if (pIn == pOut && full)
  53.       return 0;
  54.  
  55.    *pIn++ = c;
  56.  
  57.    if (pIn >= pEnd)
  58.       pIn = buf;
  59.  
  60.    if (pIn == pOut)
  61.       full = 1;
  62.  
  63.    return 1;
  64. }
  65.  
  66.  
  67. int buf_get(char *pc)
  68. {
  69.    if (pIn == pOut && !full)
  70.       return 0;
  71.  
  72.    *pc = *pOut++;
  73.    *(pOut - 1) = 0;
  74.    if (pOut >= pEnd)
  75.       pOut = buf;
  76.  
  77.    full = 0;
  78.    return 1;
  79. }
  80.  
  81. //**************************************************
  82. //  LISTA KONSUMENTOW
  83.  
  84. typedef struct
  85. {
  86.     int nCurrent;
  87.     int nMax;
  88.     int nHead;      //indeks pierwszego elementu w kolejce;
  89.     int nTail;      //indeks pierwszej wolnej pozycji na końcu kolejki;
  90.     int *pTab;
  91. }Queue;
  92.  
  93.  
  94. int QEmpty(Queue* Q)
  95. {
  96.     return !(Q->nCurrent);
  97. }
  98.  
  99. Queue* QCreate(int nSize)
  100. {
  101.     Queue* Q = (Queue*)calloc(1, sizeof(Queue));
  102.     if (!Q)
  103.     {
  104.         fprintf(stderr, "QCreate() : ERROR : Blad podczas tworzenia kolejki!\n\n");
  105.         return NULL;
  106.     }
  107.     Q->pTab = (int*)calloc(1, sizeof(int)*nSize);
  108.     if (!Q->pTab)
  109.     {
  110.         fprintf(stderr, "QCreate() : Blad!\n\n");
  111.         return NULL;
  112.     }
  113.     Q->nMax = nSize;
  114.     return Q;
  115. }
  116.  
  117. //=============================================================;
  118.  
  119. void QEnqueue(Queue* Q, int x)
  120. {
  121.     if (Q->nCurrent == Q->nMax)
  122.     {
  123.         fprintf(stderr, "QEnqueue() : ERROR : Kolejka pelna!\n\n");
  124.         return;
  125.     }
  126.     Q->pTab[Q->nTail] = x;
  127.     Q->nCurrent++;
  128.     Q->nTail = (Q->nTail + 1) % Q->nMax;
  129. }
  130.  
  131. //=============================================================;
  132.  
  133. int QDequeue(Queue* Q)
  134. {
  135.     if (QEmpty(Q))
  136.     {
  137.         //perror("QDequeue : ERROR : Kolejka pusta!\n\n");
  138.         return -1;
  139.     }
  140.     int x = Q->pTab[Q->nHead];
  141.     Q->pTab[Q->nHead] = 0;
  142.     Q->nCurrent--;
  143.     Q->nHead = (Q->nHead + 1) % Q->nMax;
  144.     return x;
  145. }
  146.  
  147. //=============================================================;
  148. /*
  149. void QDel(Queue** Q)
  150. {
  151.     QClear(*Q);
  152.     free((*Q)->pTab);
  153.     free(*Q);
  154.     *Q = NULL;
  155. }
  156. */
  157. //********************************************************
  158. //
  159. int main(int argc, char * argv[])
  160. {
  161.    int t=0; // tempo wytwarzania materialu
  162.    long port=0;
  163.    char adres[100]="localhost";
  164.    char* r_path = NULL;
  165.    r_path = CheckingParameters(argc, argv, &t, adres, &port);
  166.  
  167.    buf_init();
  168.  
  169.    char c = 'A';
  170.    int data_size = BUFSIZE;
  171.    int il_mat, il_wydan;
  172.  
  173.    // LISTA KONSUMENTOW
  174.  
  175.    int nSize = 1000;
  176.    Queue* Q = QCreate(nSize);
  177.  
  178.    // BUFOR
  179.    char *send_buf = (char*) malloc (SENDSIZE * sizeof(char));
  180.    if(send_buf == NULL){
  181.     fprintf(stderr, "Could not allocate memory!");
  182.     exit(1);
  183.    }
  184.  
  185.    char rec_buf[4];
  186.    struct sockaddr_in addr;
  187.    struct pollfd fds[1000];
  188.    struct hostent * server;
  189.    int clCon;
  190.    int rc, on = 1;
  191.    int list_sd = -1, new_connection = -1;
  192.    int end = 0, nfds=1, raport=0;
  193.    int il_blocks =0;
  194.  
  195.   // RAPORT
  196.    raport = open( r_path, O_APPEND | O_WRONLY | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
  197.    if( raport == -1){
  198.      fprintf(stderr, "Error in function open()\n");
  199.      exit(1);
  200.    }
  201.    
  202.    list_sd = socket(AF_INET, SOCK_STREAM, 0);
  203.    if (list_sd < 0)
  204.    {
  205.      fprintf(stderr, "Error in function socket()\n");
  206.      exit(-1);
  207.    }
  208.  
  209.    server = gethostbyname(adres);
  210.    if(server == NULL)
  211.    {
  212.       fprintf(stderr, "Wrong adress \n");
  213.       exit(-1);
  214.    }
  215.  
  216.   rc = setsockopt(list_sd, SOL_SOCKET,  SO_REUSEADDR, (char *)&on, sizeof(on));
  217.   if (rc < 0)
  218.      error("setsockopt()", list_sd);
  219.  
  220.   rc = ioctl(list_sd, FIONBIO, (char *)&on);
  221.   if (rc < 0)
  222.      error("ioctl()", list_sd);
  223.  
  224.  //**************************                        
  225.  
  226.   memset(&addr, 0, sizeof(addr));
  227.   addr.sin_addr.s_addr = inet_addr(adres);
  228.   addr.sin_family = AF_INET;
  229.   bcopy((char*)server->h_addr, (char*)&addr.sin_addr.s_addr, server->h_length);
  230.   addr.sin_port = htons(port);
  231.  
  232.   rc = bind(list_sd, (struct sockaddr *)&addr, sizeof(addr));
  233.   if (rc < 0)
  234.      error("bind()", list_sd);
  235.  
  236.   rc = listen(list_sd, 128);
  237.   if (rc < 0)
  238.      error("listen()", list_sd);                          
  239.  
  240.   memset(fds, 0 , sizeof(fds));
  241.   fds[0].fd = list_sd;
  242.   fds[0].events = POLLIN;
  243.  
  244.   // TIMERS
  245.  
  246.    struct itimerspec amountP;           // timer dla parametru
  247.    int clock_p = timerfd_create(CLOCK_REALTIME, 0);
  248.    amountP.it_value.tv_sec = 0;
  249.    amountP.it_value.tv_nsec = (t*60/96);
  250.    amountP.it_interval.tv_sec = 0;
  251.    amountP.it_interval.tv_nsec = (t*60/96);
  252.    if(timerfd_settime(clock_p, 0, &amountP, NULL) == -1){
  253.       fprintf(stderr, "Error in function timerfd_settime\n");
  254.       exit(1);
  255.    }
  256.  
  257.    struct itimerspec amountS;           // timer co 5 sekund
  258.    int clock_s = timerfd_create(CLOCK_REALTIME, 0);
  259.    amountS.it_value.tv_sec = 5;
  260.    amountS.it_value.tv_nsec = 0;
  261.    amountS.it_interval.tv_sec = 5;
  262.    amountS.it_interval.tv_nsec = 0;
  263.    if(timerfd_settime(clock_s, 0, &amountS, NULL) == -1){
  264.       fprintf(stderr, "Error in function timerfd_settime\n");
  265.       exit(1);
  266.    }
  267.  
  268.    nfds = 3;
  269.    fds[1].fd = clock_p;
  270.    fds[1].events = POLLIN;
  271.    fds[2].fd = clock_s;
  272.    fds[2].events = POLLIN;
  273.  
  274. while(1)
  275. {
  276.   do{
  277.     rc = poll(fds, nfds, 60000);
  278.     if (rc < 0){
  279.       fprintf(stderr, "Error in function poll()\n");
  280.       break;
  281.     }
  282.  
  283.     if (rc == 0){
  284.       fprintf(stderr, "Waiting too long (poll()). The end\n");
  285.       break;
  286.     }
  287.  
  288.     while( Take_from_Buffer(&data_size, buf, send_buf) != -1 && QEmpty(Q)==0)
  289.     {
  290.        printf("Ile w kolejce: %d \n" , QEmpty(Q));
  291.        Take_from_Buffer(&data_size, buf, send_buf);
  292.        printf("Teraz bedzie wysylal \n");
  293.        rc = send(QDequeue(Q), send_buf, 180, 0);
  294.        if (rc < 0){
  295.           fprintf(stderr, "Error in function send()\n");
  296.           clCon = 1;
  297.           break;
  298.        }
  299.     }
  300.        
  301.     for (int i = 0; i < nfds; i++)
  302.     {
  303.       if(fds[i].revents == 0)
  304.         continue;
  305.  
  306.       if (fds[i].fd == list_sd)
  307.       {
  308.         do
  309.         {
  310.           new_connection = accept(list_sd, NULL, NULL);
  311.           if (new_connection < 0)
  312.       {
  313.             if (errno != EWOULDBLOCK){
  314.               perror("Error in function accept()");
  315.               end = 1;
  316.             }
  317.             break;
  318.           }
  319.          
  320.           //* RAPORT 1
  321.           char * rap1 = "\n**************************************\n After connect: \n";
  322.           Raporting(rap1, raport, strlen(rap1));
  323.           GettingTime(raport);
  324.           Raporting( inet_ntoa(addr.sin_addr), raport, sizeof(inet_ntoa(addr.sin_addr))+1);
  325.  
  326.           printf("******************** \nNew connection\n");
  327.           fds[nfds].fd = new_connection;
  328.           fds[nfds].events = POLLIN;
  329.           nfds++;
  330.  
  331.         } while(new_connection != -1);
  332.       }
  333.       //ZEGAR   1
  334.       else if(fds[i].fd == clock_p)  
  335.       {
  336.      char clockp_buf[8];
  337.          int r = read(clock_p, clockp_buf, 8);
  338.      c = Add_to_Buffer( &data_size, c, buf, &il_mat);
  339.       }
  340.       // ZEGAR 2
  341.       else if(fds[i].fd == clock_s)
  342.       {
  343.      printf("Teraz 3 \n");
  344.      char clocks_buf[8];
  345.          int r = read(clock_s, clocks_buf, 8);
  346.      //RAPORT 3
  347.      Raport3(raport,data_size, &il_mat,&il_wydan, nfds);
  348.       }
  349.  
  350.       else
  351.       {
  352.          clCon =0;
  353.      printf("Teraz bedzie odbieral\n");
  354.      rc = recv(fds[i].fd, rec_buf, sizeof(rec_buf), 0);
  355.      if(CheckingRcv(rc, &clCon) == -1)
  356.      QEnqueue(Q, fds[i].fd);
  357.      printf("Teraz dodal do kolejki\n");
  358.      if(clCon)
  359.      {
  360.         close(fds[i].fd);
  361.         fds[i].fd = -1;
  362.           //* RAPORT 2
  363.             Raport2( &il_blocks, raport, inet_ntoa(addr.sin_addr));
  364.      }
  365.       }
  366.      }  
  367.     } while (end == 0);  
  368.  
  369.   for (int i = 0; i < nfds; i++)
  370.   {
  371.      if(fds[i].fd >= 0)
  372.      close(fds[i].fd);
  373.   }
  374.  
  375. }
  376.   free(send_buf);
  377.   close(raport);
  378.   return 0;
  379. }
  380.  
  381.  
  382. //*********************************************************
  383.  
  384. char Add_to_Buffer(int * data_size, char cc, char buf[], int* il_mat)
  385. {
  386.    char c = cc;
  387.  
  388.    if (*data_size >= GIVESIZE) // jeżeli jest miejsce na blok
  389.    {
  390.       if (c == '[')
  391.           c = 'a';
  392.       else if (c == '{')
  393.           c = 'A';
  394.  
  395.       for (int k = 0; k < GIVESIZE; k++) // przekazuje blok
  396.           buf_put(c);
  397.  
  398.       *data_size -= GIVESIZE;
  399.       c++;
  400.       *il_mat+=GIVESIZE;
  401.    }
  402.  
  403.    return c;
  404. }
  405.  
  406. //*******************************************************************
  407.  
  408. int Take_from_Buffer(int * data_size, char buf[], char * send_buf)
  409. {
  410.    if (SENDSIZE <= BUFSIZE - *data_size) // jezeli jest odpowiednia ilosc danych
  411.    {
  412.       char p[1];
  413.       for (int j = 0; j < SENDSIZE; j++)
  414.       {
  415.          buf_get(p);
  416.          *(send_buf+j)=p[0];
  417.          //printf("%c, ", *(send_buf+j));
  418.       }
  419.  
  420.       *data_size += SENDSIZE;
  421.       return 0;
  422.    }
  423.  
  424.    return -1;
  425. }
  426.  
  427. //**********************************************************
  428.  
  429.  void Raport2( int * il_blocks, int raport, char * adrIp)
  430.           {
  431.  
  432.           char * rap2 = "\n**************************************\n After disconnect: \n";
  433.           Raporting(rap2, raport, strlen(rap2));
  434.           GettingTime(raport);
  435.           Raporting( adrIp, raport, sizeof(adrIp)+1);
  436.           int blocksize = sizeof(*il_blocks);
  437.           char block_il[blocksize];
  438.           sprintf(block_il, "%d", *il_blocks);
  439.           strcat(block_il, " - ilosc przeslanych blokow\n");
  440.           Raporting( block_il, raport, strlen(block_il));
  441.           }
  442.  
  443.  
  444.  
  445. //**********************************************************
  446. void Raport3(int raport, int data_size, int *il_mat, int *il_wydan, int nfds)
  447. {
  448.  
  449.    //Raport 3
  450.    char * rap3 = "\n*************************************\n Raport after 5 seconds: \n";
  451.    Raporting(rap3, raport, strlen(rap3));
  452.    
  453.    // TS
  454.    GettingTime(raport);
  455.          
  456.    // zajetosc magazynow
  457.    char procent[sizeof((data_size*100)/BUFSIZE)];
  458.    char ile_danych[sizeof(data_size)+sizeof(procent)+20];
  459.    sprintf(ile_danych, "%d", data_size);
  460.    strcat(ile_danych, " - zajetosc magazynu \t");
  461.    sprintf(procent, "%d", data_size*100/BUFSIZE);
  462.    strcat(ile_danych, procent);
  463.    strcat(ile_danych, "%\n");
  464.    Raporting(ile_danych, raport, strlen(ile_danych));
  465.  
  466.    // przeplyw materialu
  467.    char przep[sizeof(*il_mat-*il_wydan)+48];
  468.    sprintf(przep, "%d", (*il_mat - *il_wydan));
  469.    strcat(przep, " - przeplyw materialu w ostatnich 5 sekundach \n");
  470.    Raporting(przep, raport, strlen(przep));
  471.  
  472.    // ilosc klientow
  473.    char klienci[sizeof(nfds-2)];
  474.    sprintf(klienci, "%d", nfds-2);
  475.    strcat(klienci, " - ilosc klientow podlaczonych \n");
  476.    Raporting(klienci, raport, strlen(klienci));
  477.  
  478.    *il_wydan =0;
  479.    *il_mat =0;
  480.    
  481. }
  482.  
  483.  
  484.  
  485. //*********************************************************
  486. void GettingTime(int raport)
  487. {  
  488.    char secM[20], nsecM[10], secR[20], nsecR[10];
  489.    char re[31] = "WALL TIME: ";
  490.    char mon[27] = "MONOTONIC: ";
  491.    int retMon, retRe;
  492.    struct timespec tsR, tsM;
  493.      
  494.    retRe = clock_gettime (CLOCK_REALTIME, &tsR);
  495.       if (retRe)
  496.           perror("clock_gettimeRe()");
  497.      
  498.    sprintf(secR, "%d", (int)(tsR.tv_sec));
  499.    sprintf(nsecR, "%ld", tsR.tv_nsec);
  500.    strcat(secR, ".");
  501.    strcat(secR, nsecR);
  502.    strcat(re, secR);
  503.    strcat(re, "\t");
  504.    Raporting(re, raport, sizeof(re));
  505.      
  506.    //***************************
  507.      
  508.    retMon = clock_gettime (CLOCK_MONOTONIC, &tsM);
  509.    if (retMon)
  510.        perror("clock_gettimeMon()");
  511.  
  512.    sprintf(secM, "%d", (int)(tsM.tv_sec));
  513.    sprintf(nsecM, "%ld", tsM.tv_nsec);
  514.    strcat(secM, ".");
  515.    strcat(secM, nsecM);
  516.    strcat(mon, secM);
  517.    strcat(mon, "\n");
  518.    Raporting(mon, raport, sizeof(mon));
  519. }
  520.  
  521. //**********************************************
  522.  
  523. void Raporting(char * buf, int raport, int count )
  524. {
  525.    ssize_t nr;
  526.    nr = write(raport, buf, count);
  527.    if(nr == -1 || nr != count)
  528.    {
  529.     fprintf(stderr, "Error in function write");
  530.     exit(1);
  531.    }
  532.  
  533.    nr = write(raport, "\n" , 1);
  534.    if(nr == -1 || nr != 1)
  535.    {
  536.         fprintf(stderr, "Error in function write");
  537.         exit(1);
  538.    }
  539. }
  540.  
  541. //**************************************************************
  542.  
  543. char* CheckingParameters(int argc, char*argv[], int* t, char *adres, long* port)
  544. {
  545.  
  546.    int opt;
  547.    char * r = NULL;
  548.    char* ptr = NULL;
  549.  
  550.  
  551.    while((opt = getopt(argc, argv, "r:t:")) != -1)
  552.    {
  553.       switch(opt)
  554.       {
  555.          case 'r':
  556.                  r = optarg;
  557.                  break;
  558.          case 't':
  559.                  *t = (int)strtol(optarg, &ptr,0);
  560.                  break;
  561.      default:
  562.          abort();
  563.       }
  564.    }
  565.  
  566.  
  567.    if (r == NULL)       //sprawdzenie czy jest r podane
  568.    {
  569.       fprintf(stderr,"-r is mandatory!\n");
  570.       exit (1);
  571.    }
  572.  
  573.    else if( !t)         // sprawdzenie czy jest t podane
  574.    {
  575.       fprintf(stderr,"-t is mandatory!\n");
  576.       exit (1);
  577.    }
  578.    else if( *t<1 && *t>8)   // sprawdzenie zakresu t
  579.    {
  580.       fprintf(stderr, "-t should have value from <1,8>\n");
  581.       exit(1);
  582.    }
  583.  
  584.    if (optind != (argc-1))  // sprawdzenie liczby parametrow
  585.    {
  586.       fprintf(stderr,"ERROR, wrong number of parameters\n");
  587.       exit(1);
  588.    }
  589.  
  590.                 // sprawdzanie poprawnosci [<addr>:]port
  591.    char* pEnds;
  592.    char * tmp = argv[optind];
  593.    strcpy( adres,strtok(tmp, "[]:"));
  594.    tmp = strtok(NULL, "[]:");
  595.    if(tmp==NULL)
  596.    {
  597.       *port = strtol(adres, &pEnds, 0);
  598.       if(*port==0)
  599.       {
  600.          fprintf(stderr,"ERROR, wrong PORT number\n");
  601.          exit(1);
  602.       }
  603.       strcpy(adres,"localhost");
  604.    }
  605.    else
  606.    {
  607.       *port = strtol(tmp, &pEnds, 0);
  608.       if(*port==0)
  609.       {
  610.          fprintf(stderr,"ERROR, wrong PORT number\n");
  611.          exit(1);
  612.       }
  613.    }  
  614.  
  615.    return r;
  616. }
  617.  
  618. //***********************************************************
  619.  
  620.  
  621. void nano(float od_czas)
  622. {
  623.   struct timespec tim, tim2;
  624.   tim.tv_sec = (int)od_czas;
  625.   tim.tv_nsec = (od_czas - tim.tv_sec) * 1000000000;
  626.  
  627.   if(nanosleep(&tim , &tim2) < 0 )
  628.          perror("nanosleep blad");
  629. }
  630.  
  631. //*************************************************************
  632.  
  633. void error(char * fun, int fd)
  634. {
  635.    fprintf(stderr, "Error in function %s \n", fun);
  636.    close(fd);
  637.    exit(-1);
  638.  
  639. }
  640.  
  641. //*************************************************************
  642.  
  643. int CheckingRcv( int rc, int * clCon)
  644. {
  645.    if (rc < 0)
  646.    {
  647.       if (errno != EWOULDBLOCK)
  648.       {
  649.          perror("Error in function recv()");
  650.          *clCon = 1;
  651.          return -1;
  652.       }
  653.    }
  654.  
  655.    if (rc == 0)
  656.    {
  657.      // printf("Connection closed\n");
  658.       *clCon = 1;
  659.       return -1;
  660.    }
  661.    return 0;
  662. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top