sockets-jo
Diferencias
Muestra las diferencias entre dos versiones de la página.
Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
sockets-jo [2014/10/29 15:33] – [Servidor Multi-Clientes con Fork] lmateu | sockets-jo [2018/08/16 13:04] (actual) – [Proxy genérico] lmateu | ||
---|---|---|---|
Línea 134: | Línea 134: | ||
#include < | #include < | ||
#include < | #include < | ||
+ | #include < | ||
+ | |||
#include " | #include " | ||
- | |||
- | /* | ||
- | * client_echo2: | ||
- | * que recibe de vuelta lo envía a su salida estándar. | ||
- | */ | ||
#define BUF_SIZE 1024 | #define BUF_SIZE 1024 | ||
int main() { | int main() { | ||
- | | + | int s; |
- | int cnt, cnt2; | + | int rc; |
- | char buf[BUF_SIZE]; | + | int cnt, cnt2; |
+ | | ||
- | | + | s = j_socket(); |
- | if (j_connect(s, | + | |
- | | + | if (rc<0) { |
- | exit(1); | + | |
- | } | + | exit(1); |
+ | | ||
- | | + | while ((cnt=read(0, |
- | if (write(s, buf, cnt) != cnt) { | + | if(write(s, buf, cnt) != cnt) { |
- | | + | perror(" |
- | exit(1); | + | |
- | } | + | } |
- | while (cnt > 0 && (cnt2=read(s, | + | while(cnt > 0) { |
- | write(1, buf, cnt2); | + | cnt2=read(s, |
- | cnt -= cnt2; | + | if (cnt2<=0) { |
- | } | + | if (cnt2==0) |
- | } | + | |
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | | ||
+ | write(1, buf, cnt2); | ||
+ | | ||
+ | } | ||
+ | | ||
- | | + | return 0; |
} | } | ||
</ | </ | ||
Línea 293: | Línea 301: | ||
while (waitpid(-1, | while (waitpid(-1, | ||
- | chld_cnt--; | + | chld_cnt--; |
signal(SIGCHLD, | signal(SIGCHLD, | ||
} | } | ||
Línea 346: | Línea 354: | ||
continue; | continue; | ||
} | } | ||
- | chld_cnt++; | + | chld_cnt++; |
if (fork() == 0) { /* Este es el hijo */ | if (fork() == 0) { /* Este es el hijo */ | ||
close(s); /* cerrar el socket que no voy a usar */ | close(s); /* cerrar el socket que no voy a usar */ | ||
Línea 365: | Línea 373: | ||
</ | </ | ||
- | === Ejercicio resuelto: | + | === Ejercicio resuelto: |
- | + | ||
- | Estudie los programas servidor-cat.c y cat-remoto.c en [[http:// | + | |
- | [[http:// | + | |
+ | Estudie los programas servidor-cat.c y cat-remoto.c en [[http:// | ||
===== Servidor Multi-Clientes con Threads ===== | ===== Servidor Multi-Clientes con Threads ===== | ||
Línea 573: | Línea 579: | ||
</ | </ | ||
- | === Ejercicio | + | === Ejercicios propuestos |
* Modifique el servidor de chat para que no reenvíe el mensaje al cliente que lo envía. | * Modifique el servidor de chat para que no reenvíe el mensaje al cliente que lo envía. | ||
* Modifique el cliente de chat para que agregue el nombre del usuario a todos los mensajes. | * Modifique el cliente de chat para que agregue el nombre del usuario a todos los mensajes. | ||
- | * Estudie el código de serv-dict2.c correspondiente al ejercicio resuelto al comienzo de esta sección. | ||
- | === Ejercicio resuelto: servidor para un diccionario inter procesos | + | === Ejercicios resueltos: === |
- | Estudie los programas serv-dict.c, | + | * Servidor para un diccionario inter procesos. |
- | [[http:// | + | * Determinar si un número es primo buscando algún factor. |
- | Es incompleta porque si un cliente consulta una llave y la llave no está definida, el cliente no | + | |
- | espera. | + | |
===== Servidor Multi-cliente con select ===== | ===== Servidor Multi-cliente con select ===== | ||
Línea 696: | 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.1414596782.txt.gz · Última modificación: 2014/10/29 15:33 por lmateu