Advertisement
paulogp

Socket: pedidos remotos

Jul 13th, 2011
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.16 KB | None | 0 0
  1. /* Cliente envia uma série de comandos para o servidor */
  2. // Apple Xcode
  3.  
  4. //  main.c
  5. //  cliente
  6. #include <netinet/in.h>
  7. #include <netdb.h>
  8. #include <unistd.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12.  
  13. #include "funcoes.h"
  14.  
  15. // stream read/write
  16. FILE *ligar_ao_servidor(struct hostent *the_host_info, int the_port)
  17. {
  18.     struct sockaddr_in the_client_addr;
  19.     int the_socket_ref;
  20.     FILE *the_fp;
  21.  
  22.     // create an endpoint for communication
  23.     the_socket_ref = socket(PF_INET, SOCK_STREAM, 0);
  24.  
  25.     if (the_socket_ref == -1)
  26.     {
  27.         perror("erro no socket");
  28.         return NULL;
  29.     }
  30.  
  31.     // fill a byte string with a byte value
  32.     memset(&the_client_addr, 0, sizeof(the_client_addr));
  33.     the_client_addr.sin_family = AF_INET;
  34.     the_client_addr.sin_addr = *((struct in_addr *) the_host_info->h_addr);
  35.     the_client_addr.sin_port = htons(the_port);
  36.  
  37.     if (connect(the_socket_ref, (struct sockaddr *) &the_client_addr, sizeof(struct sockaddr_in)) < 0)
  38.     {
  39.         perror("erro na ligacao");
  40.         return NULL;
  41.     }
  42.  
  43.     // stream open function
  44.     the_fp = fdopen(the_socket_ref, "r+");
  45.     if (the_fp == NULL)
  46.     {
  47.         close(the_socket_ref);
  48.     }
  49.  
  50.     // return stream
  51.     return the_fp;
  52. }
  53.  
  54.  
  55. int main(int argc, const char * argv[])
  56. {
  57.     veiculo_t v1;
  58.  
  59.     int the_port;
  60.     struct hostent* the_host_info;
  61.     char the_user_option;
  62.     char the_buffer[100];
  63.     char *the_flag;
  64.     FILE *the_fp;
  65.  
  66.     // input arguments
  67.     if (argc != 3)
  68.     {
  69.         printf("utilizacao do programa: %s ip_servidor numero_porta\n", argv[0]);
  70.         exit(1);
  71.     }
  72.  
  73.     // do it only once
  74.     // get network host entry
  75.     the_host_info = gethostbyname(argv[1]);
  76.     // convert ASCII string to integer
  77.     the_port = atoi(argv[2]);
  78.  
  79.     do
  80.     {
  81.         printf("1: inserir registo\n");
  82.         printf("2: imprimir registos\n");
  83.         printf("3: apagar registo\n\n");
  84.         printf("4: sair\n");
  85.  
  86.         // user option
  87.         // get a line from a stream
  88.         fgets(the_buffer, sizeof(the_buffer), stdin);
  89.         // input format conversion
  90.         sscanf(the_buffer, "%c", &the_user_option);
  91.  
  92.         switch (the_user_option)
  93.         {
  94.             case '1':
  95.                 // insert record
  96.                 ler_registo(&v1);
  97.  
  98.                 // output record
  99.                 imprimir_registo(&v1);
  100.  
  101.                 // connect to server
  102.                 the_fp = ligar_ao_servidor(the_host_info, the_port);
  103.  
  104.                 if (the_fp == NULL)
  105.                 {
  106.                     printf("erro na ligacao.");
  107.                     return -1;
  108.                 }
  109.  
  110.                 // send user option
  111.                 fputc('1', the_fp);
  112.  
  113.                 // send proprietario
  114.                 // binary stream input/output
  115.                 fwrite(v1.proprietario, sizeof(char), strlen(v1.proprietario), the_fp);
  116.  
  117.                 // send delimeter
  118.                 fputc('\n', the_fp);
  119.  
  120.                 // send matricula
  121.                 fwrite(v1.matricula, sizeof(char), 6, the_fp);
  122.  
  123.                 // close a stream
  124.                 fclose(the_fp);
  125.             break;
  126.  
  127.             case '2':
  128.                 // output all records
  129.                 the_fp = ligar_ao_servidor(the_host_info, the_port);
  130.  
  131.                 if (the_fp == NULL)
  132.                 {
  133.                     printf("erro na ligacao.");
  134.                     return -1;
  135.                 }
  136.  
  137.                 // send user option
  138.                 fputc('2', the_fp);
  139.  
  140.                 // read data
  141.                 while (fgets(the_buffer, sizeof(the_buffer), the_fp) != NULL)
  142.                 {
  143.                     // read proprietario
  144.                     strcpy(v1.proprietario, the_buffer);
  145.                     the_flag = strchr(v1.proprietario, '\n');
  146.  
  147.                     *the_flag = '\0';
  148.  
  149.                     // read matricula
  150.                     fread (v1.matricula, sizeof(char), 6, the_fp);
  151.  
  152.                     v1.apagado = '\0';
  153.  
  154.                     imprimir_registo(&v1);
  155.                 }
  156.  
  157.                 // close a stream
  158.                 fclose (the_fp);
  159.             break;
  160.  
  161.             case '3':
  162.                 // delete record
  163.                 printf("matricula a eliminar: ");
  164.                 fgets(the_buffer, sizeof(the_buffer), stdin);
  165.  
  166.                 the_fp = ligar_ao_servidor(the_host_info, the_port);
  167.  
  168.                 if (the_fp == NULL)
  169.                 {
  170.                     printf("erro na ligacao.");
  171.                     return -1;
  172.                 }
  173.  
  174.                 // send user option
  175.                 fputc('3', the_fp);
  176.  
  177.                 // send matricula
  178.                 fwrite(the_buffer, sizeof(char), 6, the_fp);
  179.  
  180.                 // close a stream
  181.                 fclose(the_fp);
  182.             break;
  183.         }
  184.     // do it until user press 4
  185.     } while (the_user_option != '4');
  186.  
  187.     return 0;
  188. }
  189.  
  190.  
  191.  
  192. //
  193. //  funcoes.c
  194. //  cliente
  195.  
  196. #include "funcoes.h"
  197.  
  198. #include <stdio.h>
  199. #include <stdlib.h>
  200. #include <string.h>
  201.  
  202.  
  203. // read record
  204. void ler_registo(veiculo_t *v)
  205. {
  206.     char the_buffer[81];
  207.     char *the_temp;
  208.  
  209.     // ini
  210.     v->apagado = '\0';
  211.  
  212.     // read proprietario
  213.     printf("proprietario: ");
  214.     // get a line from a stream
  215.     fgets(the_buffer, sizeof(the_buffer), stdin);
  216.  
  217.     // remove char '\n'
  218.     // locate character in string
  219.     the_temp = strchr(the_buffer, '\n');
  220.  
  221.     if (the_temp != NULL)
  222.     {
  223.         *the_temp = '\0';
  224.     }
  225.  
  226.     // copy strings
  227.     strcpy(v->proprietario, the_buffer);
  228.  
  229.     // read matricula
  230.     printf("matricula: ");
  231.     // get a line from a stream
  232.     fgets(the_buffer, sizeof(the_buffer), stdin);
  233.  
  234.     // copy only 6 chars
  235.     // copy memory area
  236.     memcpy(v->matricula, the_buffer, sizeof(v->matricula));
  237. }
  238.  
  239.  
  240. // print record
  241. void imprimir_registo(veiculo_t *v)
  242. {
  243.     // 0: if record deleted: ignored
  244.     if (v->apagado == '\0')
  245.     {
  246.         int i;
  247.         char the_aux[7];
  248.  
  249.         // copy matricula to the_aux[] as string
  250.         for (i = 0; i < 6; i++)
  251.         {
  252.             the_aux[i] = v->matricula[i];
  253.         }
  254.  
  255.         the_aux[i] = '\0';
  256.  
  257.         printf("proprietario: %-10s com matricula: %s apagada: %d\n", v->proprietario, the_aux, v->apagado);
  258.     }
  259. }
  260.  
  261.  
  262. //
  263. //  funcoes.h
  264. //  cliente
  265.  
  266. #ifndef HEADER
  267. #define HEADER
  268.  
  269. #define NAME_BUFFER_SIZE 80
  270.  
  271. typedef struct
  272. {
  273.     char matricula[6];
  274.     char proprietario[NAME_BUFFER_SIZE];
  275.     char apagado; // 0: record not deleted
  276. } veiculo_t;
  277.  
  278. void ler_registo(veiculo_t *v);
  279. void imprimir_registo(veiculo_t *v);
  280.  
  281. #endif //HEADER
  282.  
  283.  
  284.  
  285. //
  286. //  main.c
  287. //  servidor
  288.  
  289. #include "srv_aux.h"
  290.  
  291. #include <netinet/in.h>
  292. #include <unistd.h>
  293. #include <stdio.h>
  294. #include <stdlib.h>
  295. #include <arpa/inet.h>
  296. #include <string.h>
  297. #include <signal.h>
  298.  
  299. int criar_socket_servidor_inet_sock_stream(int the_port);
  300. void atende_pedido(int);
  301.  
  302. void sigalrm_handler(int signum)
  303. {
  304.     printf("timeout!\n");
  305. }
  306.  
  307. int main(int argc, const char * argv[])
  308. {
  309.     int ns, s;
  310.     unsigned int the_client_length;
  311.     struct sockaddr_in the_client_addr;
  312.  
  313.     // input arguments
  314.     if (argc != 2)
  315.     {
  316.         printf("utilizacao do programa: %s numero_porta\n", argv[0]);
  317.         exit(1);
  318.     }
  319.  
  320.     // simplified software signal facilities
  321.     signal(SIGPIPE, SIG_IGN);
  322.  
  323.     // needed to accept SIGALRM from func alarm
  324.     struct sigaction act;
  325.     act.sa_handler = sigalrm_handler;
  326.     act.sa_flags = 0;
  327.     sigemptyset(&(act.sa_mask));
  328.     sigaction(SIGALRM, &act, NULL);
  329.  
  330.     s = criar_socket_servidor_inet_sock_stream(atoi(argv[1]));
  331.  
  332.     while(1)
  333.     {
  334.         printf("a aguardar ligacao:\n");
  335.         the_client_length = sizeof(the_client_addr);
  336.  
  337.         // accept connection
  338.         ns = accept(s, (struct sockaddr *) &the_client_addr, &the_client_length);
  339.  
  340.         if (ns == -1)
  341.         {
  342.             perror("erro accept");
  343.             sleep(1);
  344.             continue;
  345.         }
  346.  
  347.         // ip and port
  348.         printf("ligacao, ip: %s, porta: %d\n", inet_ntoa(*((struct in_addr *) &(the_client_addr.sin_addr))), ntohs(the_client_addr.sin_port));
  349.  
  350.         atende_pedido(ns);
  351.     }
  352.  
  353.     return 0;
  354. }
  355.  
  356.  
  357. void atende_pedido(int ns)
  358. {
  359.     // stream open function
  360.     FILE *the_fp = fdopen(ns, "r+");
  361.  
  362.     if (the_fp == NULL)
  363.     {
  364.         perror("erro na abertura");
  365.         close(ns);
  366.  
  367.         return;
  368.     }
  369.  
  370.     // get next character or word from input stream
  371.     char the_user_option = fgetc(the_fp);
  372.  
  373.     printf("operacao: %c\n", the_user_option);
  374.  
  375.     switch(the_user_option)
  376.     {
  377.         case '1':
  378.             // server add record requested by the client
  379.             srv_adicionarRegisto(the_fp);
  380.         break;
  381.  
  382.         case '2':
  383.             // server outputs records requested by client
  384.             srv_listarRegistos(the_fp);
  385.         break;
  386.  
  387.         case '3':
  388.             // server delete record requested by the client
  389.             srv_eliminarRegisto(the_fp);
  390.         break;
  391.  
  392.         default:
  393.             // invalid option
  394.             printf("opcao invalida\n");
  395.         break;
  396.     }
  397.  
  398.     // close a stream
  399.     fclose(the_fp);
  400. }
  401.  
  402.  
  403. int criar_socket_servidor_inet_sock_stream(int the_port)
  404. {
  405.     int the_socket_ref;
  406.     struct sockaddr_in the_serv_addr;
  407.  
  408.     // create an endpoint for communication
  409.     the_socket_ref = socket(PF_INET, SOCK_STREAM, 0);
  410.  
  411.     if (the_socket_ref == -1)
  412.     {
  413.         perror("erro no socket");
  414.         exit(1);
  415.     }
  416.  
  417.     // fill a byte string with a byte value
  418.     memset(&the_serv_addr, 0, sizeof(the_serv_addr));
  419.     the_serv_addr.sin_family = AF_INET;
  420.     the_serv_addr.sin_addr.s_addr = INADDR_ANY;
  421.     the_serv_addr.sin_port = htons(the_port);
  422.  
  423.     if (bind(the_socket_ref, (struct sockaddr *)&the_serv_addr, sizeof(the_serv_addr)) < 0)
  424.     {
  425.         perror("erro na atrib");
  426.         exit(1);
  427.     }
  428.  
  429.     // listen for connections on a socket
  430.     listen(the_socket_ref, 5);
  431.  
  432.     // the return value is a descriptor referencing the socket
  433.     return(the_socket_ref);
  434. }
  435.  
  436.  
  437. //
  438. //  srv_aux.c
  439. //  servidor
  440.  
  441. #include "srv_aux.h"
  442.  
  443. #include <stdlib.h>
  444. #include <stdio.h>
  445. #include <string.h>
  446.  
  447. #define FILE_NAME "dados.dat"
  448.  
  449. void srv_adicionarRegisto(FILE *the_fp)
  450. {
  451.     char the_buffer[100];
  452.     char *the_search;
  453.  
  454.     // binary stream input
  455.     fread(the_buffer, sizeof(char), sizeof(the_buffer), the_fp);
  456.  
  457.     // search for delimiter
  458.     // locate character in string
  459.     the_search = strchr(the_buffer, '\n');
  460.     *the_search = '\0';
  461.  
  462.     veiculo_t registo;
  463.  
  464.     // copy memory area
  465.     memcpy(registo.proprietario, the_buffer, the_search + 1 - the_buffer);
  466.  
  467.     the_search++;
  468.     // copy memory area
  469.     memcpy(registo.matricula, the_search, 6);
  470.  
  471.     // insert record into file
  472.     // stream open function: file
  473.     FILE *the_file = fopen(FILE_NAME, "a");
  474.  
  475.     if (the_file != NULL)
  476.     {
  477.         // binary stream input/output: file
  478.         fwrite(&registo, sizeof(veiculo_t), 1, the_file);
  479.  
  480.         imprimir_registo(&registo);
  481.  
  482.         // close a stream: file
  483.         fclose (the_file);
  484.     }
  485. }
  486.  
  487.  
  488. // output records
  489. void srv_listarRegistos(FILE *the_fp)
  490. {
  491.     // stream open function: file
  492.     FILE *the_file = fopen(FILE_NAME, "r");
  493.  
  494.     if (the_file == NULL)
  495.     {
  496.         printf("erro na abertura do ficheiro\n");
  497.         return;
  498.     }
  499.  
  500.     veiculo_t v1;
  501.  
  502.     // fread: binary stream input
  503.     while (fread(&v1, sizeof(veiculo_t), 1, the_file) != 0)
  504.     {
  505.         // if record not deleted
  506.         if (v1.apagado == 0)
  507.         {
  508.             // write proprietario to file
  509.             fwrite(v1.proprietario, sizeof (char), strlen(v1.proprietario), the_fp);
  510.  
  511.             // displays proprietario
  512.             puts(v1.proprietario);
  513.  
  514.             // write delimeter to file
  515.             fputc('\n', the_fp);
  516.  
  517.             // write matricula to file
  518.             fwrite(v1.matricula, sizeof (char), 6, the_fp);
  519.         }
  520.     }
  521.  
  522.     // close a stream: file
  523.     fclose (the_file);
  524. }
  525.  
  526.  
  527. void srv_eliminarRegisto(FILE *the_fp)
  528. {
  529.     // stream open function: file
  530.     FILE *the_file = fopen(FILE_NAME, "r+");
  531.  
  532.     if (the_file == NULL)
  533.     {
  534.         printf("erro na abertura do ficheiro\n");
  535.         return;
  536.     }
  537.  
  538.     veiculo_t veiculo;
  539.     char the_file_value[7];
  540.     char the_comp_value[20];
  541.     int the_num_of_elements = 0;
  542.  
  543.     // from socket
  544.     // binary stream input
  545.     fread(the_comp_value, sizeof(char), sizeof(the_comp_value), the_fp);
  546.     the_comp_value[6] = '\0';
  547.  
  548.     while (fread(&veiculo, sizeof(veiculo_t), 1, the_file) != 0)
  549.     {
  550.         // get right position
  551.         the_num_of_elements++;
  552.  
  553.         // matricula to string
  554.         // copy memory area
  555.         memcpy(the_file_value, veiculo.matricula, 6);
  556.         the_file_value[6] = '\0';
  557.  
  558.         // if matricula exits, set record matricula to apagado = 1
  559.         // compare strings
  560.         if (strcmp(the_comp_value, the_file_value) == 0)
  561.         {
  562.             // delete record
  563.             veiculo.apagado = '1';
  564.  
  565.             // point to right position
  566.             // reposition a stream
  567.             fseek(the_file, (the_num_of_elements - 1) * sizeof(veiculo_t), SEEK_SET);
  568.  
  569.             // write it back
  570.             fwrite(&veiculo, sizeof(veiculo_t), 1, the_file);
  571.  
  572.             break;
  573.         }
  574.     }
  575.  
  576.     // close a stream: file
  577.     fclose(the_file);
  578. }
  579.  
  580.  
  581. // print record
  582. void imprimir_registo(veiculo_t *v)
  583. {
  584.     // 0: if record deleted: ignored
  585.     if (v->apagado == '\0')
  586.     {
  587.         int i;
  588.         char the_aux[7];
  589.  
  590.         // copy matricula to the_temp[] as string
  591.         for (i = 0; i < 6; i++)
  592.         {
  593.             the_aux[i] = v->matricula[i];
  594.         }
  595.  
  596.         the_aux[i] = '\0';
  597.         printf("proprietario: %-10s com matricula: %s apagada: %d\n", v->proprietario, the_aux, v->apagado);
  598.     }
  599. }
  600.  
  601.  
  602. //
  603. //  srv_aux.h
  604. //  servidor
  605.  
  606. #ifndef INCLUDE_SRV_AUX_H
  607. #define INCLUDE_SRV_AUX_H
  608.  
  609. #define NAME_BUFFER_SIZE 80
  610.  
  611. #include <stdio.h>
  612.  
  613. typedef struct
  614. {
  615.     char matricula[6];
  616.     char proprietario[NAME_BUFFER_SIZE];
  617.     char apagado; // 0: record not deleted
  618. } veiculo_t;
  619.  
  620. void srv_adicionarRegisto(FILE *the_fp);
  621. void srv_listarRegistos(FILE *the_fp);
  622. void srv_eliminarRegisto (FILE *the_fp);
  623. void imprimir_registo(veiculo_t *v);
  624.  
  625. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement