Si, creo que se lo que te esta pasando, y sigue siendo gracias al buen
señor que invento los strings ASCIIZ :)
Resulta que si mandas el \0 final vos estas mandando tres mensajes de
(appx) 25 cada uno con su \0 al final.
Si el escritor mando varios mensajes (mas de uno) antes que el lector
los pudiera consumir, al primer read() va a traer en los 50 bytes el
primer mensaje completo (incluyendo \0 final :) y parte del segundo
mensaje. Cuando haces printf() del buffer se frena en el primer \0 y
da la sensacion que el contenido del segundo "se perdio" aunque en
verdad esta ahi en el buffer. Si imprimis el contenido byte por byte
hasta llegar al valor de la var "leido" (y no con printf("%s")) vas a
ver exactamente lo que esta pasando.

Saludos!

2008/10/22 San Martín, Matías <[EMAIL PROTECTED]>:
> Es cierto lo que vos decis, pero aun corrigiendo esos errores el
> comportamiento extraño sigue pasando. Si al escritor le digo que mande
> el \0 del final de las cadenas (en la linea: 'size_t count =
> strlen(cadena);// + 1' descomento el + 1) me siguen llegando mal los
> mensajes del otro lado.
> Por ejemplo, si dejo todo como esta (con las correcciones indicadas
> [1] ) y descomento el '// + 1' la salida que obtengo es:
>
> 7386: Mensaje numero 1 pid: 7387
>
> 7386: 7387
>
> Si dejo comentado anda todo ok.
>
> Lo extraño tambien es que si cambio el tamaño del buffer de lectura por
> ejemplo poniendolo en 21, la salida que obtengo es
>
> 7467: Mensaje numero 1 pid
> 7467: : 7472
>
> 7467: ro 2 pid: 7472
>
> 7467: aje numero 3 pid: 74
> 7467: 72
>
>
> alguna pista de que puede ser?
>
> saludos
>
>
> [1] el bloque de codigo que cambio con las correcciones queda:
>
> const unsigned short count = 51; //tamaño del buffer de lectura
> char buf[count];
> memset(buf,0,count);
>
> while ((leido = read(fd, buf,count-1)) > 0)
>
> El mié, 22-10-2008 a las 08:34 -0300, juanii escribió:
>> Hay dos problemas:
>> El primero es que no inicializas el buffer del lector antes de la
>> primer lectura del FIFO, por lo cual si el read trajera menos de 50
>> bytes lo que queda en el resto del buffer es indefinido. El printf()
>> va a imprimir el buffer hasta encontrar un \0. Si tuviste la suerte de
>> que el destino pusiera un \0 en algun lugar del buffer, tendras el
>> mensaje mas un poco de basura. Si no tuviste esa suerte, vas a estar
>> accediendo a memoria ajena :)
>> El segundo problema es parecido al otro pero mas sutil. Resulta que,
>> bajo ciertas circunstancias la concurrencia te esta jugando en contra.
>> El proceso escritor puede ser mucho mas rapido que el lector y
>> escribir mas de 50 bytes en el FIFO antes que el lector lo lea por
>> primera vez. Si se da ese caso (y se da) el primer read() llena el
>> buffer con 50 bytes, pero como el buffer *es* de 50 bytes y estas de
>> vuelta en el primer problema, no hay \0 final. La solucion mas facil
>> es que pongas un buffer de 51 bytes y el ultimo lo dejes en \0
>> siempre.
>>
>> Saludos!
>>
>> 2008/10/21 San Martín, Matías <[EMAIL PROTECTED]>:
>> > buenas gente, a ver si alguno me puede ayudar con este problema.
>> > La idea es que tengo un proceso lector y uno escritor que se comunican
>> > mediante un FIFO. El proceso lector crea el FIFO y el escritor le manda 3
>> > mensajes.Despues el escritor cierra su fd y cuando el lector obtiene un 0
>> > como resultado del read cierra el suyo y elimina el FIFO.
>> > El asunto es que el lector me recibie mal los mensajes si el escritor le
>> > manda el \0 del final y no entiendo por que.
>> > No se si ayuda pero,un dato curioso es qeu dependiendo de que tamaño tenga
>> > el buffer de lectura (que determina en cuantas leidas recibo una cadena)
>> > recibo distintos mensajes.
>> > Si hago al escritor que no mande el \0 del final anda todo ok.
>> > Alguien tiene alguna pista de porque puede ser este comportamiento??
>> >
>> > Les mando el codigo por si les sirve para algo:
>> >
>> > ________________________________
>> >
>> > #include <cstdio>
>> > #include <cstdlib>
>> > #include <cstring>
>> > #include <sys/types.h>
>> > #include <sys/stat.h>
>> > #include <unistd.h>
>> > #include <fcntl.h>
>> > #include <errno.h>
>> >
>> > #define CANT_MAX_ESCRITORES 1//10
>> > #define NOMBRE_FIFO "./miPipe"
>> >
>> > #include <sys/wait.h>
>> >
>> > using namespace std;
>> >
>> > int main(int argc, char **argv) {
>> >
>> > pid_t nuevoPid = 0;
>> >
>> > //se lanzan todos los procesos desde el mismo proceso padre
>> > for (unsigned i = CANT_MAX_ESCRITORES; i-- && ((nuevoPid = fork()) > 0); );
>> >
>> > if (nuevoPid == -1){perror("No se pudo crear proceso\n");exit(1);}
>> >
>> > if (nuevoPid == 0)
>> > {//proceso hijo, escritor
>> >
>> > int fd;
>> > /* Si la tubería no existe cuando el proceso escritor intenta abrirla,
>> > * el escritor vuelve a intentarlo cada segundo hasta que pueda abrirla */
>> > while (((fd = open(NOMBRE_FIFO,O_WRONLY)) == -1) && (errno == ENOENT))
>> > sleep(1);
>> >
>> > if (fd == -1){perror("No se pudo abrir el FIFO para escritura\n");exit(1);}
>> >
>> > //se escriben los 3 mensajes en el FIFO
>> > const unsigned short tamBufCadena = 50;
>> > char cadena[tamBufCadena];
>> > for (unsigned short nmensaje = 1; nmensaje <= 3;nmensaje++)
>> > {
>> > memset(cadena,0,tamBufCadena);
>> > sprintf( cadena, "Mensaje numero %d pid: %d\n", nmensaje, getpid() );
>> > size_t count = strlen(cadena);// + 1;  <============= ACA SI AGREGO EL +1 
>> > SE
>> > COMPORTA DE LA FORMA "EXTRAÑA" DICHA
>> > size_t escritoTotal;
>> > ssize_t escrito;
>> > escritoTotal = 0;
>> >
>> > while ((escritoTotal < count) && ((escrito = write(fd, ((char*)cadena) +
>> > escritoTotal,count - escritoTotal)) > 0) )
>> > escritoTotal += escrito;
>> >
>> > if (escrito == -1){perror("No se pudo escribir en el FIFO\n");exit(1);}
>> > }
>> >
>> > if (close(fd) == -1){perror("No se pudo cerrar el FIFO de
>> > escritura\n");exit(1);}
>> >
>> > exit(0);
>> > }
>> >
>> > //proceso padre, lector
>> >
>> > //se crea el FIFO con permisos los permisos adecuados
>> > if (mknod(NOMBRE_FIFO,S_IFIFO | 0666,0) == -1){perror("No se pudo crear el
>> > FIFO\n");exit(1);}
>> >
>> > int fd;
>> >
>> > if ((fd = open(NOMBRE_FIFO,O_RDONLY)) == -1){perror("No se pudo abrir el
>> > FIFO para lectura\n");exit(1);}
>> >
>> > ssize_t leido;
>> > const unsigned short count = 50; //tamaño del buffer de lectura
>> > char buf[count];
>> >
>> > //se lee del FIFO hasta que se cierra (devuelve 0) o hay error (devuelve 
>> > -1)
>> > while ((leido = read(fd, buf,count)) > 0)
>> > {
>> > printf("%d: %s\n",getpid(),buf);
>> > memset(buf,0,count);
>> > }
>> >
>> > if (leido == -1){perror("No se pudo leer del FIFO\n");exit(1);}
>> >
>> > if (close(fd) == -1){perror("No se pudo cerrar el FIFO de
>> > lectura\n");exit(1);}
>> > //se elimina el fifo
>> > if (unlink(NOMBRE_FIFO) == -1){perror("No se pudo eliminar el
>> > FIFO\n");exit(1);}
>> > return 0;
>> >
>> > }
>> >
>> > ________________________________
>> >
>> > saludos, se agradece cualquier comentario,
>> > _______________________________________________
>> > Lista de correo Programacion.
>> > [email protected]
>> > http://listas.fi.uba.ar/mailman/listinfo/programacion
>> >
>> >
>>
>>
>>
>
> _______________________________________________
> Lista de correo Programacion.
> [email protected]
> http://listas.fi.uba.ar/mailman/listinfo/programacion
>



-- 
juanii

_______________________________________________
Lista de correo Programacion.
[email protected]
http://listas.fi.uba.ar/mailman/listinfo/programacion

Responder a