Advertisement
paulogp

SISTC T4 - Aplicação multi-thread

Jul 13th, 2011
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.22 KB | None | 0 0
  1. /* SISTC T4 - Aplicação multi-thread */
  2.  
  3. // Apple Xcode
  4.  
  5.  
  6. //  func.c
  7.  
  8. #include "func.h"
  9.  
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <signal.h>
  13. #include <sys/wait.h>
  14. #include <errno.h>
  15.  
  16. void ler_registo(veiculo_t *v)
  17. {
  18.     char the_aux[8];
  19.  
  20.     printf("\nmatricula: ");
  21.     // get a line from a stream
  22.     fgets(the_aux, 8, stdin);
  23.     // copy memory area
  24.     memcpy(v->matricula, the_aux, 6);
  25.  
  26.     printf("\nproprietario: ");
  27.     // get a line from a stream
  28.     fgets(v->proprietario, NAME_BUFFER_SIZE, stdin);
  29.  
  30.     v->apagado = '0';
  31. }
  32.  
  33. void imprimir_registo(veiculo_t *v)
  34. {  
  35.     if (v->apagado == '0')
  36.     {
  37.         printf("\nproprietario\n %s ", v->proprietario);
  38.         printf("\n matricula\n");
  39.         fwrite(v->matricula, 6, 1, stdout);
  40.     }
  41. }
  42.  
  43. void apagar_registo(char matricula[], FILE *the_record)
  44. {  
  45.     veiculo_t v1;
  46.  
  47.     // binary stream input/output
  48.     while (fread(&v1, sizeof(v1), 1, the_record) != 0)
  49.     {
  50.         // compare strings
  51.         if (strncmp(matricula, v1.matricula, 6) == 0)
  52.         {
  53.             v1.apagado = '1';
  54.             // reposition a stream
  55.             fseek(the_record, -sizeof(v1), SEEK_CUR);
  56.             fwrite(&v1, sizeof(v1), 1, the_record);
  57.         }
  58.     }  
  59. }
  60.  
  61.  
  62. //
  63. //  func.h
  64.  
  65. #include <stdio.h>
  66.  
  67. #define NAME_BUFFER_SIZE 80
  68.  
  69. typedef struct
  70. {
  71.     char matricula[6];
  72.     char proprietario[NAME_BUFFER_SIZE];
  73.     char apagado;
  74. } veiculo_t;
  75.  
  76. void ler_registo(veiculo_t *);
  77. void imprimir_registo(veiculo_t *);
  78. void apagar_registo(char *, FILE *);
  79.  
  80. //void sigchld_handler(int);
  81.  
  82.  
  83. //
  84. //  main.c
  85. //  servidor
  86.  
  87. #include "func.h"
  88.  
  89. #include <stdio.h>
  90. #include <netinet/in.h>
  91. #include <unistd.h>
  92. #include <string.h>
  93. #include <stdlib.h>
  94. #include <arpa/inet.h>
  95. #include <pthread.h>
  96. #include <semaphore.h>
  97.  
  98. #define PROP "proprietario"
  99.  
  100. void atende_pedido(int);
  101. int prepara_socket_servidor(int the_port);
  102.  
  103. int the_request = 0;
  104. int the_count = 0;
  105.  
  106. // to define a semaphore object, use: sem_t sem_name;
  107. sem_t the_semaphore;
  108.  
  109. // mutex is an abbreviation for "mutual exclusion".
  110. // mutex variables are one of the primary means of implementing
  111. // thread synchronization and for protecting shared data when
  112. // multiple writes occur
  113. pthread_mutex_t the_mutex = PTHREAD_MUTEX_INITIALIZER;
  114.  
  115. // server socket PF_INET
  116. // communication type SOCK_STREAM
  117. int main (int argc, const char * argv[])
  118. {
  119.     int the_ns;
  120.  
  121.     struct sockaddr_in the_client_address;
  122.     unsigned int the_client_length;
  123.  
  124.     // initialize the semaphore in the main function
  125.     sem_init(&the_semaphore, 0, 0);
  126.  
  127.     if (argc != 2)
  128.     {
  129.         printf("utilizacao: %s numero_porta\n", argv[0]);
  130.         exit(1);
  131.     }
  132.  
  133.     // atoi: convert ASCII string to integer
  134.     int the_socket = prepara_socket_servidor(atoi(argv[1]));
  135.  
  136.     the_client_length = sizeof(the_client_address);
  137.  
  138.     while(1)
  139.     {
  140.         printf("aguardar ligacao\n");
  141.  
  142.         // accept/reject jobs sent to a destination
  143.         the_ns = accept(the_socket, (struct sockaddr *) &the_client_address, &the_client_length);
  144.         printf("ligacao de %s\n", inet_ntoa(*((struct in_addr *) &(the_client_address.sin_addr))));
  145.         atende_pedido(the_ns);
  146.     }
  147.  
  148.     return 0;
  149. }
  150.  
  151. int prepara_socket_servidor(int the_port)
  152. {
  153.     struct sockaddr_in the_server_address;
  154.  
  155.     // create an endpoint for communication
  156.     int the_socket = socket(PF_INET, SOCK_STREAM, 0);
  157.  
  158.     if (the_socket < 0)
  159.     {
  160.         perror("erro no socket");
  161.         exit(1);
  162.     }
  163.  
  164.     // fill a byte string with a byte value
  165.     memset(&the_server_address, 0, sizeof(the_server_address));
  166.     the_server_address.sin_family = AF_INET;
  167.     the_server_address.sin_addr.s_addr = INADDR_ANY;
  168.     the_server_address.sin_port = htons(the_port);
  169.  
  170.     if (bind(the_socket, (struct sockaddr *)&the_server_address, sizeof(the_server_address)) < 0)
  171.     {
  172.         perror("erro na ligacao");
  173.         exit(1);
  174.     }    
  175.  
  176.     // listen for connections on a socket
  177.     listen(the_socket, 5);
  178.  
  179.     return the_socket;
  180. }
  181.  
  182. void *output_thread(void *the_fp)
  183. {
  184.     veiculo_t v1;
  185.  
  186.     FILE *the_record = fopen(PROP, "a+");
  187.  
  188.     while(fread(&v1, sizeof(v1), 1, the_record) != 0)
  189.     {
  190.         if (v1.apagado == '0')
  191.         {
  192.             fwrite(&v1, sizeof(v1), 1, the_fp);
  193.         }
  194.     }
  195.  
  196.     fclose(the_record);
  197.     fclose(the_fp);
  198.  
  199.     // prevent "the_count" changes when simultaneous connections occurs
  200.     pthread_mutex_lock(&the_mutex);
  201.     the_count--;
  202.     pthread_mutex_unlock(&the_mutex);
  203.  
  204.     if ((the_count == 0) && (the_request == 1))
  205.     {
  206.         // increments the value of the semaphore and wakes up
  207.         // a blocked process waiting on the semaphore, if any
  208.         sem_post(&the_semaphore);
  209.         the_request--;
  210.     }
  211.  
  212.     return (NULL);
  213. }
  214.  
  215. void atende_pedido(int ns)
  216. {
  217.     veiculo_t v1;
  218.     pthread_t the_tid;
  219.     char matricula[8];
  220.     char the_temp[8];
  221.  
  222.     FILE *the_record;
  223.  
  224.     // stream open function
  225.     FILE *the_fp = fdopen(ns, "r+");
  226.  
  227.     if (the_fp == NULL)
  228.     {
  229.         perror("fdopen");
  230.         close(ns);
  231.         return;
  232.     }
  233.  
  234.     // get next character or word from input stream
  235.     char the_option = fgetc(the_fp);
  236.  
  237.     switch(the_option)
  238.     {
  239.         case '1':
  240.             the_record = fopen(PROP, "a+");
  241.  
  242.             fgets(v1.proprietario, NAME_BUFFER_SIZE, the_fp);
  243.             fgetc(the_fp);
  244.             fgets(the_temp, 8, the_fp);
  245.             memcpy(v1.matricula, the_temp, 6);
  246.  
  247.             v1.apagado = '0';
  248.  
  249.             if (the_count != 0)
  250.             {  
  251.                 the_request++;
  252.                 // wait on a semaphore
  253.                 sem_wait(&the_semaphore);  
  254.             }
  255.  
  256.             fwrite(&v1, sizeof(v1), 1, the_record);
  257.             fclose(the_record);
  258.             fclose(the_fp);
  259.         break;
  260.  
  261.         case '2':
  262.             // prevent "the_count" changes when simultaneous connections occurs
  263.             pthread_mutex_lock(&the_mutex);
  264.             the_count++;
  265.             pthread_mutex_unlock(&the_mutex);
  266.  
  267.             pthread_create(&the_tid, NULL, output_thread, the_fp);
  268.             pthread_detach(the_tid);
  269.         break;
  270.  
  271.         case '3':
  272.             the_record = fopen(PROP, "r+");
  273.             // binary stream input/output
  274.             fread(matricula, 8, 1, the_fp);
  275.             apagar_registo(matricula, the_record);
  276.             fclose(the_record);
  277.             fclose(the_fp);
  278.         break;
  279.     }
  280. }
  281.  
  282.  
  283. //
  284. //  main.c
  285. //  cliente
  286.  
  287. #include "func.h"
  288.  
  289. #include <stdio.h>
  290. #include <stdlib.h>
  291. #include <netinet/in.h>
  292. #include <netdb.h>
  293. #include <unistd.h>
  294. #include <string.h>
  295.  
  296. FILE *ligar_ao_servidor(struct hostent* the_host_info, int the_port)
  297. {
  298.     // create an endpoint for communication
  299.     int the_socket = socket(PF_INET, SOCK_STREAM, 0);
  300.  
  301.     if (the_socket < 0)
  302.     {
  303.         perror("erro no socket");
  304.         return NULL;
  305.     }
  306.  
  307.     struct sockaddr_in the_address;
  308.     // fill a byte string with a byte value
  309.     memset(&the_address, 0, sizeof(the_address));
  310.     the_address.sin_family = AF_INET;
  311.     the_address.sin_addr = *((struct in_addr *)the_host_info->h_addr);
  312.     the_address.sin_port = htons(the_port);
  313.  
  314.     // initiate a connection on a socket
  315.     if (connect(the_socket, (struct sockaddr *) &the_address, sizeof(struct sockaddr_in)) < 0)
  316.     {
  317.         perror("erro na ligacao");
  318.         return NULL;
  319.     }
  320.  
  321.     // stream open function
  322.     FILE *the_fp = fdopen(the_socket, "r+");
  323.  
  324.     if (the_fp == NULL)
  325.     {
  326.         close(the_socket);
  327.     }
  328.  
  329.     return the_fp;
  330. }
  331.  
  332. int main (int argc, const char * argv[])
  333. {
  334.     veiculo_t v1;
  335.  
  336.     char the_matricula[8];
  337.     FILE *the_fp;
  338.  
  339.     if (argc != 3)
  340.     {
  341.         printf("utilizacao: %s ip_servidor numero_porta\n",argv[0]);
  342.         exit(1);
  343.     }
  344.  
  345.     // do it once
  346.     struct hostent *the_host_info = gethostbyname(argv[1]);  
  347.     int the_port = atoi(argv[2]);
  348.  
  349.     int the_option;
  350.  
  351.     do
  352.     {  
  353.         printf("\n1: inserir registo");
  354.         printf("\n2: visualizar registos");
  355.         printf("\n3: apagar registo");
  356.         printf("\n\n4: sair do programa\n");
  357.  
  358.         scanf("%d", &the_option);
  359.         getchar();
  360.  
  361.         switch(the_option)
  362.         {
  363.             case 1:
  364.                 ler_registo(&v1);
  365.                 the_fp = ligar_ao_servidor(the_host_info, the_port);
  366.                 fputc('1', the_fp);
  367.  
  368.                 // output a line to a stream
  369.                 fputs(v1.proprietario, the_fp);
  370.                 fputc('\n', the_fp);
  371.  
  372.                 fputs(v1.matricula, the_fp);
  373.  
  374.                 // flush a stream
  375.                 fflush(the_fp);
  376.  
  377.                 fclose(the_fp);    
  378.             break;
  379.  
  380.             case 2:
  381.                 the_fp = ligar_ao_servidor(the_host_info, the_port);
  382.                 fputc('2', the_fp);
  383.  
  384.                 while(fread(&v1, sizeof(v1), 1, the_fp) !=0)
  385.                 {
  386.                     imprimir_registo(&v1);
  387.                 }
  388.  
  389.                 fclose(the_fp);
  390.             break;
  391.  
  392.             case 3:
  393.                 printf("\nmatricula: ");
  394.                 fgets(the_matricula, 8, stdin);
  395.  
  396.                 the_fp = ligar_ao_servidor(the_host_info, the_port);
  397.                 fputc('3', the_fp);
  398.  
  399.                 fwrite(the_matricula, 8, 1, the_fp);
  400.                 fclose(the_fp);
  401.             break;
  402.  
  403.             case 4:
  404.             break;
  405.  
  406.             default:
  407.                 printf("opcao invalida");
  408.             break;
  409.         }
  410.     } while(the_option != 4);
  411.  
  412.     return 0;
  413. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement