Advertisement
Guest User

Untitled

a guest
Feb 16th, 2019
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.39 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement