Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <sys/types.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <string.h>
- #include <arpa/inet.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <ctype.h>
- #include <sys/ioctl.h>
- #include <sys/poll.h>
- #include <sys/time.h>
- #include <errno.h>
- #include <netdb.h>
- #include <time.h>
- #include <sys/timerfd.h>
- void Raporting(char * buf, int raport, int count);
- char* CheckingParameters(int argc, char*argv[], int* t, char* adres, long* port);
- void nano(float od_czas);
- void error(char* fun, int fd);
- int CheckingRcv(int rc, int * clCon);
- char makeBuffer(int * data_size, char cc, char buf[], char* send_buf );
- void GettingTime( int raport);
- char Add_to_Buffer(int * data_size, char cc, char buf[], int* il_mat);
- int Take_from_Buffer(int * data_size, char buf[], char * send_buf);
- void Raport3(int raport, int data_size, int *il_mat, int *il_wydan, int nfds);
- // BUFOR
- #define BUFSIZE 200 // rozmiar bufora
- #define GIVESIZE 3 // rozmiar bloku do wypelniania
- #define SENDSIZE 180 // rozmiar pobieranych danych
- char buf[BUFSIZE];
- char *pIn, *pOut, *pEnd;
- char full;
- void buf_init()
- {
- pIn = pOut = buf;
- pEnd = &buf[BUFSIZE];
- full = 0;
- }
- int buf_put(char c)
- {
- if (pIn == pOut && full)
- return 0;
- *pIn++ = c;
- if (pIn >= pEnd)
- pIn = buf;
- if (pIn == pOut)
- full = 1;
- return 1;
- }
- int buf_get(char *pc)
- {
- if (pIn == pOut && !full)
- return 0;
- *pc = *pOut++;
- *(pOut - 1) = 0;
- if (pOut >= pEnd)
- pOut = buf;
- full = 0;
- return 1;
- }
- //**************************************************
- // LISTA KONSUMENTOW
- typedef struct
- {
- int nCurrent;
- int nMax;
- int nHead; //indeks pierwszego elementu w kolejce;
- int nTail; //indeks pierwszej wolnej pozycji na końcu kolejki;
- int *pTab;
- }Queue;
- int QEmpty(Queue* Q)
- {
- return !(Q->nCurrent);
- }
- Queue* QCreate(int nSize)
- {
- Queue* Q = (Queue*)calloc(1, sizeof(Queue));
- if (!Q)
- {
- fprintf(stderr, "QCreate() : ERROR : Blad podczas tworzenia kolejki!\n\n");
- return NULL;
- }
- Q->pTab = (int*)calloc(1, sizeof(int)*nSize);
- if (!Q->pTab)
- {
- fprintf(stderr, "QCreate() : Blad!\n\n");
- return NULL;
- }
- Q->nMax = nSize;
- return Q;
- }
- //=============================================================;
- void QEnqueue(Queue* Q, int x)
- {
- if (Q->nCurrent == Q->nMax)
- {
- fprintf(stderr, "QEnqueue() : ERROR : Kolejka pelna!\n\n");
- return;
- }
- Q->pTab[Q->nTail] = x;
- Q->nCurrent++;
- Q->nTail = (Q->nTail + 1) % Q->nMax;
- }
- //=============================================================;
- int QDequeue(Queue* Q)
- {
- if (QEmpty(Q))
- {
- //perror("QDequeue : ERROR : Kolejka pusta!\n\n");
- return -1;
- }
- int x = Q->pTab[Q->nHead];
- Q->pTab[Q->nHead] = 0;
- Q->nCurrent--;
- Q->nHead = (Q->nHead + 1) % Q->nMax;
- return x;
- }
- //=============================================================;
- /*
- void QDel(Queue** Q)
- {
- QClear(*Q);
- free((*Q)->pTab);
- free(*Q);
- *Q = NULL;
- }
- */
- //********************************************************
- int main(int argc, char * argv[])
- {
- int t=0; // tempo wytwarzania materialu
- long port=0;
- char adres[100]="localhost";
- char* r_path = NULL;
- r_path = CheckingParameters(argc, argv, &t, adres, &port);
- buf_init();
- char c = 'A';
- int data_size = BUFSIZE;
- int il_mat;
- int il_wydan;
- //*************************************
- // LISTA KONSUMENTOW
- int nSize = 1000;
- Queue* Q = QCreate(nSize);
- //**************************************
- // BUFOR
- char *send_buf = (char*) malloc (SENDSIZE * sizeof(char));
- if(send_buf == NULL)
- {
- printf("Could not allocate memory!");
- exit(1);
- }
- //**************************************
- char rec_buf[4];
- struct sockaddr_in addr;
- struct pollfd fds[1000];
- struct hostent * server;
- int clCon;
- int rc, on = 1;
- int list_sd = -1, new_connection = -1;
- int end = 0;
- int nfds = 1;
- int raport =0;
- int il_blocks =0;
- int change_size=0;
- //**************************************
- // RAPORT
- raport = open( r_path, O_APPEND | O_WRONLY | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
- if( raport == -1)
- {
- fprintf(stderr, "Error in function open()\n");
- exit(1);
- }
- ///Take_Element(&L);
- //*********************
- list_sd = socket(AF_INET, SOCK_STREAM, 0);
- if (list_sd < 0)
- {
- fprintf(stderr, "Error in function socket()\n");
- exit(-1);
- }
- server = gethostbyname(adres);
- if(server == NULL)
- {
- fprintf(stderr, "Wrong adress \n");
- exit(-1);
- }
- rc = setsockopt(list_sd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
- if (rc < 0)
- error("setsockopt()", list_sd);
- rc = ioctl(list_sd, FIONBIO, (char *)&on);
- if (rc < 0)
- error("ioctl()", list_sd);
- //**************************
- memset(&addr, 0, sizeof(addr));
- addr.sin_addr.s_addr = inet_addr(adres);
- addr.sin_family = AF_INET;
- bcopy((char*)server->h_addr, (char*)&addr.sin_addr.s_addr, server->h_length);
- addr.sin_port = htons(port);
- rc = bind(list_sd, (struct sockaddr *)&addr, sizeof(addr));
- if (rc < 0)
- error("bind()", list_sd);
- rc = listen(list_sd, 128);
- if (rc < 0)
- error("listen()", list_sd);
- memset(fds, 0 , sizeof(fds));
- fds[0].fd = list_sd;
- fds[0].events = POLLIN;
- // TIMERS
- struct itimerspec amountP; // timer dla parametru
- int clock_p = timerfd_create(CLOCK_REALTIME, 0);
- amountP.it_value.tv_sec = 0;
- amountP.it_value.tv_nsec = (t*60/96);
- amountP.it_interval.tv_sec = 0;
- amountP.it_interval.tv_nsec = (t*60/96);
- if(timerfd_settime(clock_p, 0, &amountP, NULL) == -1)
- {
- fprintf(stderr, "Error in function timerfd_settime\n");
- exit(1);
- }
- struct itimerspec amountS; // timer co 5 sekund
- int clock_s = timerfd_create(CLOCK_REALTIME, 0);
- amountS.it_value.tv_sec = 5;
- amountS.it_value.tv_nsec = 0;
- amountS.it_interval.tv_sec = 5;
- amountS.it_interval.tv_nsec = 0;
- if(timerfd_settime(clock_s, 0, &amountS, NULL) == -1)
- {
- fprintf(stderr, "Error in function timerfd_settime\n");
- exit(1);
- }
- nfds = 3;
- fds[1].fd = clock_p;
- fds[1].events = POLLIN;
- fds[2].fd = clock_s;
- fds[2].events = POLLIN;
- //**********************
- while (end == 0)
- {
- rc = poll(fds, nfds, 60000);
- if (rc < 0)
- {
- fprintf(stderr, "Error in function poll()\n");
- break;
- }
- if (rc == 0)
- {
- fprintf(stderr, "Waiting too long (poll()). The end\n");
- break;
- }
- for (int i = 0; i < nfds; i++)
- {
- if(fds[i].revents == 0)
- continue;
- if (fds[i].fd == list_sd)
- {
- do
- {
- new_connection = accept(list_sd, NULL, NULL);
- if (new_connection < 0)
- {
- if (errno != EWOULDBLOCK)
- {
- perror("Error in function accept()");
- end = 1;
- }
- break;
- }
- //* RAPORT 1
- char * rap1 = "\n**************************************\n After connect: \n";
- Raporting(rap1, raport, strlen(rap1));
- GettingTime(raport);
- Raporting( inet_ntoa(addr.sin_addr), raport, sizeof(inet_ntoa(addr.sin_addr))+1);
- //***************
- printf("******************** \nNew connection\n");
- fds[nfds].fd = new_connection;
- fds[nfds].events = POLLIN;
- nfds++;
- } while(new_connection != -1);
- }
- //ZEGAR 1
- else if(fds[i].fd == clock_p)
- {
- char clockp_buf[8];
- int r = read(clock_p, clockp_buf, 8);
- c = Add_to_Buffer( &data_size, c, buf, &il_mat);
- }
- // ZEGAR 2
- else if(fds[i].fd == clock_s)
- {
- char clocks_buf[8];
- int r = read(clock_s, clocks_buf, 8);
- //RAPORT 3
- Raport3(raport,data_size, &il_mat,&il_wydan, nfds);
- }
- // KOLEJNE POLACZENIA
- else
- {
- int il_rcv=0;
- clCon = 0;
- il_blocks=0;
- while(1)
- {
- // Wysylanie i odbieranie danych
- printf("petla sie zaczyna\n");
- rc = recv(fds[i].fd, rec_buf, sizeof(rec_buf),0);
- if ( CheckingRcv(rc, &clCon) == -1)
- break;
- printf("Received bytes: %d\n", rc);
- int if_give = Take_from_Buffer(&data_size, buf, send_buf);
- if(if_give==-1)
- {
- printf("Braklo materialu\n");
- QEnqueue(Q,fds[i].fd);
- printf("Dodano element\n ");
- }
- else if(if_give!=-1)
- {
- int que=QDequeue(Q);
- if(que!=-1)
- {
- printf("Biore z kolejki i wysylam\n");
- // for(int r=0; i<SENDSIZE; i++)
- // printf("%c,", send_buf[0]);
- rc = send(que, send_buf, 180, 0);
- if (rc < 0)
- {
- fprintf(stderr, "Error in function sssend()\n");
- clCon = 1;
- break;
- }
- il_rcv--;
- printf(" Dane wyslane:\n");
- for(int r=0; i<SENDSIZE; i++)
- printf("%c,", send_buf[0]);
- //break;
- }
- else
- {
- printf("Teraz mam wyslac \n");
- // for(int r=0; i<180; i++)
- // printf("%c,,,", *(send_buf+i));
- rc = send(fds[i].fd, send_buf, 180, 0);
- if (rc < 0)
- {
- fprintf(stderr, "Error in function send()\n");
- clCon = 1;
- break;
- }
- //break;
- }
- for(int k=0; k<SENDSIZE; k++)
- *(send_buf+k)=0;
- il_blocks++;
- il_wydan+=SENDSIZE;
- }
- printf("Wychodzi z petli\n");
- // continue;
- }
- if (clCon)
- {
- close(fds[i].fd);
- fds[i].fd = -1;
- change_size = 1;
- //* RAPORT 2
- char * rap2 = "\n**************************************\n After disconnect: \n";
- Raporting(rap2, raport, strlen(rap2));
- GettingTime(raport);
- Raporting( inet_ntoa(addr.sin_addr), raport, sizeof(inet_ntoa(addr.sin_addr))+1);
- int blocksize = sizeof(il_blocks);
- char block_il[blocksize];
- sprintf(block_il, "%d", il_blocks);
- strcat(block_il, " - ilosc przeslanych blokow\n");
- Raporting( block_il, raport, strlen(block_il));
- //*********************
- }
- }
- }
- if (change_size)
- {
- for (int m = 0; m < nfds; m++)
- {
- if (fds[m].fd == -1)
- {
- for(int n = m; n < nfds; n++)
- fds[n].fd = fds[n+1].fd;
- nfds--;
- }
- }
- change_size = 0;
- }
- }
- for (int i = 0; i < nfds; i++)
- {
- if(fds[i].fd >= 0)
- close(fds[i].fd);
- }
- free(send_buf);
- close(raport);
- return 0;
- }
- //*********************************************************
- char Add_to_Buffer(int * data_size, char cc, char buf[], int* il_mat)
- {
- char c = cc;
- if (*data_size >= GIVESIZE) // jeżeli jest miejsce na blok
- {
- if (c == '[')
- c = 'a';
- else if (c == '{')
- c = 'A';
- for (int k = 0; k < GIVESIZE; k++) // przekazuje blok
- buf_put(c);
- *data_size -= GIVESIZE;
- c++;
- *il_mat+=GIVESIZE;
- }
- return c;
- }
- //*******************************************************************
- int Take_from_Buffer(int * data_size, char buf[], char * send_buf)
- {
- if (SENDSIZE <= BUFSIZE - *data_size) // jezeli jest odpowiednia ilosc danych
- {
- char p[1];
- for (int j = 0; j < SENDSIZE; j++)
- {
- buf_get(p);
- *(send_buf+j)=p[0];
- printf("%c, ", *(send_buf+j));
- }
- *data_size += SENDSIZE;
- return 0;
- }
- return -1;
- }
- //**********************************************************
- void Raport3(int raport, int data_size, int *il_mat, int *il_wydan, int nfds)
- {
- //Raport 3
- char * rap3 = "\n*************************************\n Raport after 5 seconds: \n";
- Raporting(rap3, raport, strlen(rap3));
- // TS
- GettingTime(raport);
- // zajetosc magazynow
- char procent[sizeof((data_size*100)/BUFSIZE)];
- char ile_danych[sizeof(data_size)+sizeof(procent)+20];
- sprintf(ile_danych, "%d", data_size);
- strcat(ile_danych, " - zajetosc magazynu \t");
- sprintf(procent, "%d", data_size*100/BUFSIZE);
- strcat(ile_danych, procent);
- strcat(ile_danych, "%\n");
- Raporting(ile_danych, raport, strlen(ile_danych));
- // przeplyw materialu
- char przep[sizeof(*il_mat-*il_wydan)+48];
- sprintf(przep, "%d", (*il_mat - *il_wydan));
- strcat(przep, " - przeplyw materialu w ostatnich 5 sekundach \n");
- Raporting(przep, raport, strlen(przep));
- // ilosc klientow
- char klienci[sizeof(nfds-2)];
- sprintf(klienci, "%d", nfds-2);
- strcat(klienci, " - ilosc klientow podlaczonych \n");
- Raporting(klienci, raport, strlen(klienci));
- *il_wydan =0;
- *il_mat =0;
- }
- //*********************************************************
- void GettingTime(int raport)
- {
- char secM[20], nsecM[10], secR[20], nsecR[10];
- char re[31] = "WALL TIME: ";
- char mon[27] = "MONOTONIC: ";
- int retMon, retRe;
- struct timespec tsR, tsM;
- retRe = clock_gettime (CLOCK_REALTIME, &tsR);
- if (retRe)
- perror("clock_gettimeRe()");
- sprintf(secR, "%d", (int)(tsR.tv_sec));
- sprintf(nsecR, "%ld", tsR.tv_nsec);
- strcat(secR, ".");
- strcat(secR, nsecR);
- strcat(re, secR);
- strcat(re, "\t");
- Raporting(re, raport, sizeof(re));
- //***************************
- retMon = clock_gettime (CLOCK_MONOTONIC, &tsM);
- if (retMon)
- perror("clock_gettimeMon()");
- sprintf(secM, "%d", (int)(tsM.tv_sec));
- sprintf(nsecM, "%ld", tsM.tv_nsec);
- strcat(secM, ".");
- strcat(secM, nsecM);
- strcat(mon, secM);
- strcat(mon, "\n");
- Raporting(mon, raport, sizeof(mon));
- }
- //**********************************************
- void Raporting(char * buf, int raport, int count )
- {
- ssize_t nr;
- nr = write(raport, buf, count);
- if(nr == -1 || nr != count)
- {
- fprintf(stderr, "Error in function write");
- exit(1);
- }
- nr = write(raport, "\n" , 1);
- if(nr == -1 || nr != 1)
- {
- fprintf(stderr, "Error in function write");
- exit(1);
- }
- }
- //**************************************************************
- char* CheckingParameters(int argc, char*argv[], int* t, char *adres, long* port)
- {
- int opt;
- char * r = NULL;
- char* ptr = NULL;
- while((opt = getopt(argc, argv, "r:t:")) != -1)
- {
- switch(opt)
- {
- case 'r':
- r = optarg;
- break;
- case 't':
- *t = (int)strtol(optarg, &ptr,0);
- break;
- default:
- abort();
- }
- }
- if (r == NULL) //sprawdzenie czy jest r podane
- {
- fprintf(stderr,"-r is mandatory!\n");
- exit (1);
- }
- else if( !t) // sprawdzenie czy jest t podane
- {
- fprintf(stderr,"-t is mandatory!\n");
- exit (1);
- }
- else if( *t<1 && *t>8) // sprawdzenie zakresu t
- {
- fprintf(stderr, "-t should have value from <1,8>\n");
- exit(1);
- }
- if (optind != (argc-1)) // sprawdzenie liczby parametrow
- {
- fprintf(stderr,"ERROR, wrong number of parameters\n");
- exit(1);
- }
- // sprawdzanie poprawnosci [<addr>:]port
- char* pEnds;
- char * tmp = argv[optind];
- strcpy( adres,strtok(tmp, "[]:"));
- tmp = strtok(NULL, "[]:");
- if(tmp==NULL)
- {
- *port = strtol(adres, &pEnds, 0);
- if(*port==0)
- {
- fprintf(stderr,"ERROR, wrong PORT number\n");
- exit(1);
- }
- strcpy(adres,"localhost");
- }
- else
- {
- *port = strtol(tmp, &pEnds, 0);
- if(*port==0)
- {
- fprintf(stderr,"ERROR, wrong PORT number\n");
- exit(1);
- }
- }
- return r;
- }
- //***********************************************************
- void nano(float od_czas)
- {
- struct timespec tim, tim2;
- tim.tv_sec = (int)od_czas;
- tim.tv_nsec = (od_czas - tim.tv_sec) * 1000000000;
- if(nanosleep(&tim , &tim2) < 0 )
- perror("nanosleep blad");
- }
- //*************************************************************
- void error(char * fun, int fd)
- {
- fprintf(stderr, "Error in function %s \n", fun);
- close(fd);
- exit(-1);
- }
- //*************************************************************
- int CheckingRcv( int rc, int * clCon)
- {
- if (rc < 0)
- {
- if (errno != EWOULDBLOCK)
- {
- perror("Error in function recv()");
- *clCon = 1;
- return -1;
- }
- }
- if (rc == 0)
- {
- printf("Connection closed\n");
- *clCon = 1;
- return -1;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement