Herramientas de usuario

Herramientas del sitio


sockets-jo

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
sockets-jo [2015/07/30 19:42] – [Cliente de chat multi-thread] lmateusockets-jo [2018/08/16 13:04] (actual) – [Proxy genérico] lmateu
Línea 699: Línea 699:
 de chat con threads: nunca se bloquea para todos los clientes. de chat con threads: nunca se bloquea para todos los clientes.
  
-===== Proxy genérico ===== 
  
-Se trata de escribir un programa que haga de "proxy" de un servidor: se trata de instalar un intermediario que simula ser un servidor, pero que en realidad "representa" a otro servidor que ahora está en otra máquina. Es como un "forwarder" que sirve para instalarlo si movemos un servidor de una máquina a otra y queremos que los clientes antiguos sigan funcionando, o para instalar en un computador que es accesible desde Internet para representar un servidor que está en un computador sin acceso a Internet (una intranet por ejemplo). La invocación de este proxy es: 
-<code> 
-% ./proxy port-in server port-out 
-</code> 
-Escucha en la máquina local conexiones que llegan a port-in, luego se conecta a (server, port-out) y luego envía y recibe todos los datos de ambos lados. Haremos dos versiones, una que crea dos procesos hijos (uno que copia en una 
-dirección del socket y otro que copia en la dirección opuesta) y otra con select que queda mejor. 
- 
-Solución con 2 hijos: 
-<code C> 
- #include <stdio.h> 
-#include <stdlib.h> 
-#include <signal.h> 
-#include <wait.h> 
-#include "jsocket.h" 
- 
-/* 
- * proxy: proxy multi-cliente usando procesos pesados 
- * Hacer version con select? 
- */ 
- 
-#define BUF_SIZE 200 
- 
-/* 
- * Esta es la forma mas simple de enterrar a los hijos sin complicarse l 
-a vida 
- */ 
-void child() { 
-    int status; 
- 
-    while(waitpid(-1, &status, WNOHANG)>0) 
- ; 
-} 
- 
-void die() { 
-    fprintf(stderr, "cliente desconectado\n"); 
-    exit(0); 
-} 
- 
-/* 
- * Este es el servidor y el codigo para un socket cliente ya conectado:  
- */ 
-void proxy(int s1, char *host, int portout) { 
-   int cnt, size = BUF_SIZE; 
-   char buf[BUF_SIZE]; 
-   int s2; 
-   int pid; 
- 
-   signal(SIGUSR1, die); 
- 
-   s2 = j_socket(); 
- 
-   if(j_connect(s2, host, portout) < 0) { 
- fprintf(stderr, "connection refused to %s/%d\n", host, portout); 
- exit(1); 
-   } 
-   fprintf(stderr, "cliente conectado\n"); 
-  
-   if((pid = fork()) < 0) { 
-    fprintf(stderr, "no pude fork\n"); 
- exit(1); 
-   } 
- 
-   if(pid == 0) { 
-    while((cnt=read(s1, buf, size)) > 0) 
-     if(write(s2, buf, cnt) < 0) break; 
- kill(getppid(), SIGUSR1); 
- exit(0); 
-   } else 
-    while((cnt=read(s2, buf, size)) > 0) 
-     if(write(s1, buf, cnt) < 0) break; 
- 
-    kill(pid, SIGKILL); 
-    fprintf(stderr, "cliente desconectado\n"); 
-} 
- 
-/* 
- * Este es el principal: solo acepta conexiones y crea a los hijos servi 
-dores 
- */ 
-main(int argc, char **argv) { 
-   int s, s2; 
-   int portin, portout; 
-   char *host; 
- 
-   if(argc != 4) { 
- fprintf(stderr, "Use: %s port-in host port-out\n", argv[0]); 
- exit(1); 
-   } 
- 
-   portin = atoi(argv[1]); 
-   host = argv[2]; 
-   portout = atoi(argv[3]); 
- 
-   signal(SIGCHLD, child); 
- 
-   s = j_socket(); 
- 
-   if(j_bind(s, portin) < 0) { 
- fprintf(stderr, "bind failed\n"); 
- exit(1); 
-   } 
- 
-   for(;;) { 
- s2 = j_accept(s); 
- if(fork() == 0) { /* Este es el hijo */ 
-     close(s); /* cerrar el socket que no voy a usar */ 
-     proxy(s2, host, portout); 
-     exit(0); 
- } else 
-     close(s2); /* cerrar el socket que no voy a usar */ 
-   } 
-} 
-</code> 
- 
-Y una mejor con select: 
-<code C> 
-#include <stdio.h> 
-#include <stdlib.h> 
-#include <signal.h> 
-#include <wait.h> 
-#include "jsocket.h" 
- 
-/* 
- * proxy: proxy multi-cliente usando procesos pesados 
- * version con select 
- */ 
- 
-#define BUF_SIZE 200 
- 
-/* 
- * Esta es la forma mas simple de enterrar a los hijos sin complicarse l 
-a vida 
- */ 
-void child() { 
-    int status; 
- 
-    while(waitpid(-1, &status, WNOHANG)>0) 
- ; 
-} 
- 
-/* 
- * Este es el servidor y el codigo para un socket cliente ya conectado:  
-s 
- */ 
-void proxy(int s1, char *host, int portout) { 
-   int cnt, size = BUF_SIZE; 
-   char buf[BUF_SIZE]; 
-   int s2; 
-   int pid; 
-   fd_set mask; 
- 
-   s2 = j_socket(); 
- 
-   if(j_connect(s2, host, portout) < 0) { 
- fprintf(stderr, "connection refused to %s/%d\n", host, portout); 
- exit(1); 
-   } 
-   fprintf(stderr, "cliente conectado\n"); 
-  
-/* 
-       int select(int numfds, fd_set *readfds, fd_set *writefds , 
-       fd_set *exceptfds, struct timeval * timeout); 
- 
-       FD_CLR(int fd, fd_set *set); 
-       FD_ISSET(int fd, fd_set *set); 
-       FD_SET(int fd, fd_set *set); 
-       FD_ZERO(fd_set * set); 
-*/ 
-    
-    
-    for(;;) { 
-        FD_ZERO(&mask); 
-        FD_SET(s1, &mask); FD_SET(s2, &mask); 
- select(getdtablesize(), &mask, NULL, NULL, NULL); 
- if(FD_ISSET(s1, &mask)) { 
-        cnt=read(s1, buf, size); 
-     if(cnt <= 0) { 
-    fprintf(stderr, "cliente desconectado\n"); 
- exit(0); 
-     } 
-     write(s2, buf, cnt); 
- } 
- if(FD_ISSET(s2, &mask)) { 
-        cnt=read(s2, buf, size); 
-     if(cnt <= 0) { 
-    fprintf(stderr, "cliente desconectado\n"); 
-  exit(0); 
-     } 
-     write(s1, buf, cnt); 
- } 
-    } 
-} 
- 
-/* 
- * Este es el principal: solo acepta conexiones y crea a los hijos servi 
-dores 
- */ 
-main(int argc, char **argv) { 
-   int s, s2; 
-   int portin, portout; 
-   char *host; 
- 
-   if(argc != 4) { 
- fprintf(stderr, "Use: %s port-in host port-out\n", argv[0]); 
- exit(1); 
-   } 
- 
-   portin = atoi(argv[1]); 
-   host = argv[2]; 
-   portout = atoi(argv[3]); 
- 
-   signal(SIGCHLD, child); 
- 
-   s = j_socket(); 
- 
-   if(j_bind(s, portin) < 0) { 
- fprintf(stderr, "bind failed\n"); 
- exit(1); 
-   } 
- 
-   for(;;) { 
- s2 = j_accept(s); 
- if(fork() == 0) { /* Este es el hijo */ 
-     close(s); /* cerrar el socket que no voy a usar */ 
-     proxy(s2, host, portout); 
-     exit(0); 
- } else 
-     close(s2); /* cerrar el socket que no voy a usar */ 
-   } 
-} 
-</code> 
- 
-=== El super demonio inetd === 
- 
-Estudie [[http://users.dcc.uchile.cl/~lmateu/CC3301/apuntes/Sockets/|el super demonio inetd]] que aparece en los apuntes de Patricio Poblete. 
  
sockets-jo.1438285347.txt.gz · Última modificación: 2015/07/30 19:42 por lmateu