views:

535

answers:

3

I'm reading/writing data off of a named pipe. On the writing side it says that it's writing a constant 110 bytes. On the Reading side for the majority of time it says that it's reading 110 bytes which is correct, but other times it says its reading 220 bytes or 330 bytes. Which is right in the fact that when I print it out it's printing out the same message two or three times in a row within the same read(). In the code below for reading am I doing something wrong with the memset to clear the char? I can't think of any other way it's reading more then is being written unless something is left over in the buffer.

int fd1, numread;
char bufpipe[5000];

 while(1)
 {
  fd1 = open("/tmp/testPipe", O_RDONLY);
  numread = read(fd1,bufpipe, 5000);//->this should always be 110
  if(numread > 1)
  {
   printf("READ: %i", numread); 
   bufpipe[numread+1] = '\0';
   memset(bufpipe,'\0',5001);
   close(fd1);
  }
 }
+1  A: 

Your assumption that a read will execute immediately after a write is not true. The writer process might write to the pipe a couple of times before a read is encountered. Written data will be added to the end of buffer. Put it differently, read and write are not packet oriented. They are stream oriented. It means that write just adds data to the buffer and read just gets anything available to it.

Mehrdad Afshari
+6  A: 

This:

memset(bufpipe,'\0',5001);

is overwriting by one byte, because you have only 5000 bytes.

But the main "problem" is that read(..., 5000) will always read as much as it can up to 5000 bytes - you seem to be assuming that it will read only as much as was written in one go by the writer, which is not true. If the writer writes two packets of 110 bytes between two reads, then it's quite correct that the reader reads 220 bytes.

If you need to read only a single packet at a time, you have to make your packets self-describing. So for instance, the first four bytes contain the number of bytes to follow. Then you can read a single packet by reading four bytes, converting that to an integer, then reading that number of data bytes.

RichieHindle
you sir are my hero. I would never have thought of that, thank you
whatWhat
A: 

How are you synchronizing with the writer? You need to just read what your expecting (specify 110 to read())

pixelbeat
Is there a way to do this without knowing what to expect? The amount being read in this case can by any amount. Thats why I have it set so high at 5000 even though it's only writing 110
whatWhat
You need your packets to include their length at the start, so you can read the length first and then the right number of bytes to get the rest of that single packet. See my amended answer.
RichieHindle