Question

I'm developing a project in which I need to connect the clients (iPhones) to a server. I've done this using CFStream, NSStream, etc. The server sends data packets that needs to be handled "one by one" in the client. The problem is that sometimes the server sends two data packets one after the other, so what I receive in the client (via [inputStream hasBytesAvailable]) is a concatenation of both data packets.

The architecture of a data packet from server to client is "data"+b'00000000' (binary NULL). I want to know how to make the program know that when there is a '00000000' byte it has to process that packet and empty the buffer.

Here is the code I'm using:

case NSStreamEventHasBytesAvailable:

    if (theStream == inputStream) {

        uint8_t buffer[1024];
        int len;

        while ([inputStream hasBytesAvailable]) {
            len = [inputStream read:buffer maxLength:sizeof(buffer)];
            if (len > 0) {

                NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];

                if (nil != output) {
                    [self processData:output];
                    NSLog(@"OUTPUT: %@", output);
                }
            }
        }
    }
    break;

An example. Server sends: msg1_whatever (concatenated with) b'0000000' And inmediatly after that, it sends: msg2_whatever + b'00000000'

Then, the NSLog will show: msg1_whatever+b'00000000'msg2_whatever+b'00000000'

Instead of two separated strings. If there is a little time between sending msg1 and msg2, then it works perfectly, but this exception needs to be handled since it's going to happen several times.

Était-ce utile?

La solution

You need to redesign your protocol. The main issue here is that you don't give the size of the message that you're sending before the message itself, and therefore you don't know how much to read from the input stream for each message.

Here's an example for a really simple protocol. Each message consists of two fields:

  1. Size (unsigned int).
  2. The message itself.

Then, for each message you read twice. First, you read the message size sizeof(unsigned int), then read the message itself (you now know its size).

This also removes the necessity for the null separator between messages, which can possibly occur inside your message if you don't escape it correctly, and can cause serious problems.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top