tags:

views:

39

answers:

4

I have a server thats sending out data records as strings of varying length(for eg, 79,80,81,82)

I want to be able to receive exactly one record at a time.I've delimited records with a (r) but because I dont know howmany bytes I have to receive, It sometimes merges records and makes it difficult for me to process.

A: 

Are you sending your data as a stream?

You can send it as a structure which is easier to parse and retrieve the data from.

struct Message
{
  int dataSize;
  char data[256];
};
bdhar
no..It has to be a stream due to some other constraints
Rajesh
Please reverse the struct - in practice, the dataSize will be sent first. I know this does not change how this works, but semantically it's clearer.
elcuco
@elcuco - Thanks for the tip. Edited accordingly :)
bdhar
A: 

You should delimit with null byte. Show us your code, and we may be able to help you.

Alexander Rafferty
unless .... you do want to send ascii(0)....
elcuco
It's the least used character, because many applications use it for separation or termination of data segments.
Alexander Rafferty
+2  A: 

I have two ideas for you:

  1. Use XML for the protocol. This way you know exactly when each message ends.
  2. Send in the header of each "packet" the packet size, this way you know how much to read from the socket for this specific packet.

Edit: Look at this dummy code for (2)

int buffer_size;
char* buffer;

read( socket, &buffer_size, sizeof(buffer_size)); 
buffer = (char*) malloc(packet_size);
read( socket, buffer, buffer_size );
// do something
free( buffer) ; 
elcuco
cant I do this without xml? I can just parse the header myself right?
Rajesh
I think this will work.Thanks
Rajesh
There is no guarantee that either `read()` will read exactly what you ask for. You have to loop around until you get the full packet size, and if you do that then you might as well loop around looking for the end-of-packet delimiter.
caf
A: 

Stream sockets do not natively support an idea of a "record" - the abstraction they provide is that of a continuous stream.

You must implement a layer on top of them to provide "records". It sounds like you are already part way there, with the end-of-record delimiter. The pseudo-code to complete it is:

create empty buffer;
forever {
    recv data and append to buffer;

    while (buffer contains end-of-record marker) {
        remove first record from buffer and process it;
        move remaining data to beginning of buffer;
    }
}
caf