sockets-jo
Diferencias
Muestra las diferencias entre dos versiones de la página.
Ambos lados, revisión anteriorRevisión previa | |||
sockets-jo [2015/07/30 19:42] – [Cliente de chat multi-thread] lmateu | sockets-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 port-in server port-out | ||
- | </ | ||
- | 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 < | ||
- | #include < | ||
- | #include < | ||
- | #include " | ||
- | |||
- | /* | ||
- | * 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, | ||
- | ; | ||
- | } | ||
- | |||
- | void die() { | ||
- | fprintf(stderr, | ||
- | 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; | ||
- | |||
- | | ||
- | |||
- | s2 = j_socket(); | ||
- | |||
- | | ||
- | fprintf(stderr, | ||
- | exit(1); | ||
- | } | ||
- | | ||
- | |||
- | | ||
- | fprintf(stderr, | ||
- | exit(1); | ||
- | } | ||
- | |||
- | | ||
- | while((cnt=read(s1, | ||
- | if(write(s2, | ||
- | kill(getppid(), | ||
- | exit(0); | ||
- | } else | ||
- | while((cnt=read(s2, | ||
- | if(write(s1, | ||
- | |||
- | kill(pid, SIGKILL); | ||
- | fprintf(stderr, | ||
- | } | ||
- | |||
- | /* | ||
- | * 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; | ||
- | |||
- | | ||
- | fprintf(stderr, | ||
- | exit(1); | ||
- | } | ||
- | |||
- | | ||
- | host = argv[2]; | ||
- | | ||
- | |||
- | | ||
- | |||
- | s = j_socket(); | ||
- | |||
- | | ||
- | fprintf(stderr, | ||
- | exit(1); | ||
- | } | ||
- | |||
- | | ||
- | 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 */ | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | Y una mejor con select: | ||
- | <code C> | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include " | ||
- | |||
- | /* | ||
- | * 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, | ||
- | ; | ||
- | } | ||
- | |||
- | /* | ||
- | * 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; | ||
- | | ||
- | |||
- | s2 = j_socket(); | ||
- | |||
- | | ||
- | fprintf(stderr, | ||
- | exit(1); | ||
- | } | ||
- | | ||
- | |||
- | /* | ||
- | int select(int numfds, fd_set *readfds, fd_set *writefds , | ||
- | | ||
- | |||
- | | ||
- | | ||
- | | ||
- | | ||
- | */ | ||
- | |||
- | |||
- | for(;;) { | ||
- | FD_ZERO(& | ||
- | FD_SET(s1, &mask); FD_SET(s2, &mask); | ||
- | select(getdtablesize(), | ||
- | if(FD_ISSET(s1, | ||
- | cnt=read(s1, | ||
- | if(cnt <= 0) { | ||
- | fprintf(stderr, | ||
- | exit(0); | ||
- | } | ||
- | write(s2, buf, cnt); | ||
- | } | ||
- | if(FD_ISSET(s2, | ||
- | cnt=read(s2, | ||
- | if(cnt <= 0) { | ||
- | fprintf(stderr, | ||
- | | ||
- | } | ||
- | 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; | ||
- | |||
- | | ||
- | fprintf(stderr, | ||
- | exit(1); | ||
- | } | ||
- | |||
- | | ||
- | host = argv[2]; | ||
- | | ||
- | |||
- | | ||
- | |||
- | s = j_socket(); | ||
- | |||
- | | ||
- | fprintf(stderr, | ||
- | exit(1); | ||
- | } | ||
- | |||
- | | ||
- | 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 */ | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | === El super demonio inetd === | ||
- | |||
- | Estudie [[http:// | ||
sockets-jo.1438285347.txt.gz · Última modificación: 2015/07/30 19:42 por lmateu