Advertisement
paulogp

Cliente / Servidor

Jul 14th, 2011
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.54 KB | None | 0 0
  1. /* Servidor que permite consultar paginas de texto remotamente.
  2.  As paginas serao visualizadas a partir do programa cliente que
  3.  implementa as seguintes funcionalidades:
  4.  - envio do nome do ficheiro a visualizar
  5.  - impressao no ecran do conteudo do ficheiro */
  6.  
  7. // Apple Xcode
  8. // paulogp
  9.  
  10.  
  11. //
  12. // servidor
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <netinet/in.h> // struct sockaddr_in
  16. #include <string.h> // bzero
  17. #include <signal.h>
  18.  
  19. #define BUFSIZE 20
  20.  
  21. void atende(int ns);
  22. void copy_stream(FILE *src, FILE *dest);
  23.  
  24. int main (int argc, const char * argv[])
  25. {
  26.     int ns, s;
  27.     struct sockaddr_in serv_addr;
  28.    
  29.     // para nao terminar caso a ligacao com o cliente seja interrompida
  30.     // durante a transmissao do ficheiro: ignorar o sinal SIG_PIPE
  31.     // caso se queira terminar: basta comentar as seguinte 5 linhas
  32.     struct sigaction act;
  33.     act.sa_handler = SIG_IGN;
  34.     act.sa_flags = 0;
  35.     sigemptyset(&(act.sa_mask));
  36.     sigaction(SIGPIPE, &act, NULL);
  37.    
  38.     //
  39.     s = socket(PF_INET, SOCK_STREAM, 0);
  40.     if (s < 0) // para o caso do sistema ja nao conseguir criar mais sockets
  41.     {
  42.         perror("socket");
  43.         exit(1);
  44.     }
  45.    
  46.     bzero((char *) &serv_addr, sizeof(serv_addr));
  47.     serv_addr.sin_family = AF_INET;
  48.     serv_addr.sin_addr.s_addr = INADDR_ANY;
  49.     serv_addr.sin_port = htons(4000);
  50.    
  51.     if (bind(s, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
  52.     {
  53.         // o porto pode estar em uso noutro processo
  54.         perror("bind");
  55.         exit(1);
  56.     }
  57.    
  58.     if (listen(s, 5) < 0)
  59.     {
  60.         // o porto pode estar em uso noutro processo
  61.         perror("socket");
  62.     }
  63.    
  64.     printf("servidor activo\n");
  65.    
  66.     while (1)
  67.     {
  68.         ns = accept(s, NULL, NULL);
  69.         if (ns < 0) // para o caso de receber algum sinal (e.g., SIGSTOP/SIGCONT)
  70.         {
  71.             perror("accept");
  72.             continue;
  73.         }
  74.        
  75.         atende(ns);
  76.     }
  77.    
  78.     return 0;
  79. }
  80.  
  81. void atende (int ns)
  82. {
  83.     char buf[BUFSIZE];
  84.     int i;
  85.     FILE *fps, *fpf;
  86.    
  87.     fps = fdopen(ns, "r+");
  88.     // ler nome do ficheiro - sequencia de caracteres terminados com '\0'
  89.     for (i = 0; (i < BUFSIZE) && ((buf[i] = fgetc(fps)) != 0); ++i);
  90.    
  91.     if (buf[i] != 0)
  92.     {
  93.         fprintf(fps, "erro na leitora do nome do ficheiro\n");
  94.         fclose(fps);
  95.         return;
  96.     }
  97.    
  98.     fpf = fopen(buf, "r");
  99.     if (fpf == NULL)
  100.     {
  101.         fprintf(fps, "erro na abertura do ficheiro %s\n", buf);
  102.         fclose(fps);
  103.         return;
  104.     }
  105.    
  106.     // ler e enviar ficheiro
  107.     copy_stream(fpf, fps);
  108.     fclose(fpf);
  109.     fclose(fps);
  110. }
  111.  
  112. void copy_stream(FILE *src, FILE *dest)
  113. {
  114.     int ch;
  115.     while ((ch = fgetc(src)) != EOF)
  116.     {
  117.         fputc(ch, dest);
  118.     }
  119. }
  120.  
  121.  
  122. //
  123. // cliente
  124. #include <stdio.h>
  125. #include <unistd.h>
  126. #include <sys/socket.h>
  127. #include <sys/types.h>
  128. #include <netinet/in.h> // struct sockaddr_in
  129. #include <netdb.h> // gethostbyname
  130. #include <string.h>
  131.  
  132. #define BUFSIZE 20
  133.  
  134. void formata_string(char *buf, unsigned long *ssize);
  135. void copy_stream(FILE *src, FILE *dest);
  136.  
  137. int main (int argc, const char * argv[])
  138. {
  139.     argv[1] = "localhost"; // para teste
  140.    
  141.     char buf[BUFSIZE];
  142.     int s;
  143.     unsigned long ssize;
  144.    
  145.     struct sockaddr_in name;
  146.     struct hostent* hostinfo;
  147.    
  148.     name.sin_family = AF_INET;
  149.     hostinfo = gethostbyname(argv[1]);
  150.     name.sin_addr = *((struct in_addr *) hostinfo->h_addr);
  151.     name.sin_port = htons(4000);
  152.    
  153.     while (1)
  154.     {
  155.         printf("nome do ficheiro: ");
  156.         fflush(stdout);
  157.         fgets(buf, BUFSIZE, stdin);
  158.         formata_string(buf, &ssize);
  159.        
  160.         s = socket(PF_INET, SOCK_STREAM, 0);
  161.         connect(s, (struct sockaddr *) &name, sizeof(struct sockaddr_in));
  162.         write(s, buf, ssize); // envia-me nome, incluindo o '\0'
  163.        
  164.         FILE *fps = fdopen(s, "r");
  165.         copy_stream(fps, stdout);
  166.         fclose(fps);
  167.     }
  168.    
  169.    
  170.     return 0;
  171. }
  172.  
  173. void copy_stream(FILE *src, FILE *dest)
  174. {
  175.     int ch;
  176.     while ((ch = fgetc(src)) != EOF)
  177.     {
  178.         fputc(ch, dest);
  179.     }
  180. }
  181.  
  182. void formata_string(char *buf, unsigned long *ssize)
  183. {
  184.     *ssize = strlen(buf);
  185.    
  186.     if (buf[*ssize - 1] == '\n') // vamos eliminar o '\n', caso exista
  187.     {
  188.         buf[*ssize - 1] = '\0'; // '\n' substituido pelo "novo" '\0'
  189.     }
  190.     else // caso nao exista, aumentamos ssize, para contar o '\0' original
  191.     {
  192.         (*ssize)++; // so acontece quando nº de chars antes do '\n' e BUFSIZE-1
  193.     }
  194. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement