[Programación] Tuberias UNIX

Tengo un programa (servidor) que se encarga de ejecutar otro programa (cliente), usando fork+exec, y pretendo que tengan una comunicación bidireccional usando dos pipe's UNIX de toda la vida. Pretendo que la entrada estandar de uno sea la salida estandar del otro y viceversa. Necesito dos tubos: uno cli2srv y otro srv2cli.
El problema que tengo es que ambos procesos se me quedan bloqueados a la espera, justo en el fgets (lo he comprobado a base de printfs), a pesar de que el servidor que deberia iniciar la conversación ya ha enviado su primer printf. Para comunicarlos, uso printf y fgets(...,...,stdin). No se lo que puede fallar. Os pego el código que considero conflictivo

   if(fork()) {    // Pare (Server)
      dup2(cli2srv[0], STDIN_FILENO);
      dup2(srv2cli[1], STDOUT_FILENO);
      close(cli2srv[0]);
      close(cli2srv[1]);
      close(srv2cli[0]);
      close(srv2cli[1]);
   } else {   // Fill (Client)
      dup2(cli2srv[1], STDOUT_FILENO);
      dup2(srv2cli[0], STDIN_FILENO);
      close(cli2srv[0]);
      close(cli2srv[1]);
      close(srv2cli[0]);
      close(srv2cli[1]);
      fprintf(stderr, "Server exec: %s\n", exec);
      execvp(exec, NULL);
      perror("execvp");
   }

   // El server inicia la comunicación y espera el cliente
   fprintf(stdout, "Semilla:\n");
   fprintf(stderr, "hola\n");
   fgets(comanda, COMBUF, stdin);


El cliente se limita a un while(1) y fgets/printfs. Por supuesto se queda atascado en el primer fgets.

¿Alguien sabe que es lo que me estoy dejando? Debe ser una tonteria pero no hay forma de dar con ella. Si necesitais más código en concreto decidlo.

Saludos y gracias por adelantado ^^

Edito: Ya lo he resuelto (llevaba unas cuantas horitas, no creais), se arregla con un
fflush(stdout);

Yo no se las horas que me ha quitado de mi vida esta función... ¬¬
Jeje , no desesperes hombre . Yo llevo 3 semanas para hacer un driver de un Lcd y todavía sigue sin funcionar :?

Está claro, los errores chorras son los más dificiles de encontrar [sonrisa]

1 Salu2
Jeje, ya vereis cuando esté acabado (que ya le queda poco), que frikada xDDD.
que utilidad va a tener? ya me he quedao con la intriga
yo tuve que hacer ese programa el año pasado pa sistemas operativos miticamente,y pedi ayuda por problema con la TDF, asi q en la busqueda avanzada hay codigo funcional :D, si tengo tiempo tambien analizaré el codigo :D, ahora estoy pegandome con oracle
marcgenou escribió:que utilidad va a tener? ya me he quedao con la intriga


es lo que iba a preguntar, y eso para que sirve ? [Alaa!]
yo lo se ... yo lo seeee !!!
Me lo han chivado.
:-P
Se trata de una especie de reto de programación sobre el tetris xDD. Se trata de crear un programa cliente que juegue lo mejor posible. Es decir, se programa un "servidor" que envia las piezas a jugar al "cliente" y el cliente le responde con los movimientos. El servidor es trivial, seria como un juego de tetris normal, pero debe comunicarse por una tuberia al cliente y el cliente por otra. El cliente ya puede ser todo lo complejo que querais.
El código que veis es para redireccionar los tubos a la salida/entrada estándar. De esta forma se simplifica el cliente ya que en vez de tener que usar tuberias pues solo tiene que hacer printf/getline.

Imagino que deben de haber ideas parecidas por ahí, pero esta me hace ilusion porque lo planeamos toda la clase junta, aunque de momento solo curro yo ^^U.
El plan final, es hacer una interfaz web para enviar programas cliente que se ejecuten contra el servidor y tengamos una especie de ranking en la web xDD. Por supuesto si quereis apuntaros a hacer clientes o a ayudar con el servidor, solo teneis que decirlo ^^. De momento el servidor aun no esta listo del todo, pero queda poco y yo ayer acabé los exámenes, jeje.

Si quereis mas info mirad aquí (en valenciano):
http://raharu.homelinux.org/phpBB2/viewtopic.php?t=135
http://raharu.homelinux.org/phpBB2/viewtopic.php?t=134

Saludos
// antes de nada se crean las tuberias
int tubo1[2],tubo2[2];
int servidor_in,cliente_in,servidor_out,cliente_out;
pipe(tubo1);
pipe(tubo2);
// esto solo pa que sentienda
servidor_in=tubo1[0];
cliente_out=tubo1[1];
cliente_in=tubo2[0];
servidor_out=tubo2[1];
if((pid=fork())==(pid_t)0)
{ /* Proceso Hijo */
// cerramos la parte del padre
close(servidor_in);
close(servidor_out);
// El cliente sera stdin y stdout
close(0); /* Cierra 'stdin' */
dup(cliente_in); /* vincula cliente_in a 'stdin' */
close(1); /* Cierra 'stdout' */
dup(cliente_out); /* vincula cliente_out a 'stdout' */
//aqui la llamada al exec
........
}
else
{/* Proceso Padre */
close(cliente_in);
close(cliente_out);
// no tiene sentido que el padre utilice stdin y stdout, puesto que tendra
// lo mas seguro que hablar con varios clientes.
/*------------------------------------------------------------*/
// con servidor_in y servidor_out tendermos que usar read y write.

}

Saludos a todos

---------------------------------------------------------------
POSDATA
---------------------------------------------------------------
Para usar fprintf y fgets en el servidor tendremos que ::

FILE *Fservidor_in;
FILE *Fservidor_out;
Fservidor_in=fdopen(servidor_in,"r");
Fservidor_out=fdopen(servidor_out,"w");

// fprintf(Fservidor_out,""%s","Prueba de escritura");
Se agradece altair ^^U, pero ya lo solucioné (mira el final del primer mensaje). Lo que sucede es que no se trata de un cliente-servidor (de ahí las comillas que usé). Solo necesitaba una comunicación en dos procesos y lógicamente tampoco es un "servidor" multicliente.

Saludoos y gracias de todas formas
Raharu escribió:Se trata de una especie de reto de programación sobre el tetris xDD. Se trata de crear un programa cliente que juegue lo mejor posible. Es decir, se programa un "servidor" que envia las piezas a jugar al "cliente" y el cliente le responde con los movimientos. El servidor es trivial, seria como un juego de tetris normal, pero debe comunicarse por una tuberia al cliente y el cliente por otra. El cliente ya puede ser todo lo complejo que querais.
El código que veis es para redireccionar los tubos a la salida/entrada estándar. De esta forma se simplifica el cliente ya que en vez de tener que usar tuberias pues solo tiene que hacer printf/getline.

Imagino que deben de haber ideas parecidas por ahí, pero esta me hace ilusion porque lo planeamos toda la clase junta, aunque de momento solo curro yo ^^U.
El plan final, es hacer una interfaz web para enviar programas cliente que se ejecuten contra el servidor y tengamos una especie de ranking en la web xDD. Por supuesto si quereis apuntaros a hacer clientes o a ayudar con el servidor, solo teneis que decirlo ^^. De momento el servidor aun no esta listo del todo, pero queda poco y yo ayer acabé los exámenes, jeje.



Joé , da gusto cuando se ven ideas que al final se materializan [buenazo] [buenazo] , lástima que no me entere del nodo del valenciano.
¿ qué hay que saber para programarse un buen jugador , RRNN , algoritmos geneticos?
Yo es que de IA ni guarra , pero algo he visto de los perceptrones multicapa :D

1 Salu2
dykstra escribió:
Joé , da gusto cuando se ven ideas que al final se materializan [buenazo] [buenazo] , lástima que no me entere del nodo del valenciano.
¿ qué hay que saber para programarse un buen jugador , RRNN , algoritmos geneticos?
Yo es que de IA ni guarra , pero algo he visto de los perceptrones multicapa :D

1 Salu2


mmm, a ver, nosotros no tenemos ni guarra de IA (este año acabamos tercero), ahí esta lo interesante: a ver que sacamos con lo que sabemos xD. Si te interesa, agregame al jabber y te informo como está el tema ;)
raharu@amessage.at

Saludos

EDITO: Ya lo he hecho oficial xDD y en castellano ;)
http://raharu.homelinux.org/index.php/?p=58
joder raharu, puede estar interesante y no esta demas decir que es una frikada importante.
Hola a todos.

Tengo un problema mas o menos parecido al que aquí se plantea. La cuestión es que debo hacer una comunicación cliente-servidor mediante pipes. La cosa consiste, en que el cliente envíe al servidor la ruta de un fichero (por ejemplo, /proc/loadavg), y no encuentro forma humana de poder escribir yo la ruta por teclado del mismo, puesto que los descriptores los redirecciono con dup2 tanto a STDIN_FILENO como a STDOUT_FILENO, según necesidad.
13 respuestas