0

我正在开发一个项目,我需要将客户端(iPhone)连接到服务器。我已经使用 CFStream、NSStream 等完成了这项工作。服务器发送需要在客户端“一一”处理的数据包。问题是有时服务器一个接一个地发送两个数据包,所以我在客户端(通过[inputStream hasBytesAvailable])收到的是两个数据包的串联。

从服务器到客户端的数据包的架构是“数据”+b'00000000'(二进制NULL)。我想知道如何让程序知道当有一个“00000000”字节时,它必须处理该数据包并清空缓冲区。

这是我正在使用的代码:

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;

一个例子。服务器发送: msg1_whatever (concatenated with) b'0000000' 之后,它立即发送: msg2_whatever + b'00000000'

然后,NSLog 将显示: msg1_whatever+b'00000000'msg2_whatever+b'00000000'

而不是两个分开的字符串。如果发送 msg1 和 msg2 之间有一点时间,那么它工作得很好,但是这个异常需要处理,因为它会发生多次。

4

1 回答 1

1

你需要重新设计你的协议。这里的主要问题是您没有在消息本身之前给出要发送的消息的大小,因此您不知道从输入流中读取每条消息的多少。

这是一个非常简单的协议的示例。每条消息包含两个字段:

  1. 大小(无符号整数)。
  2. 消息本身。

然后,对于您阅读两次的每条消息。首先,您阅读消息大小sizeof(unsigned int),然后阅读消息本身(您现在知道它的大小)。

这也消除了消息之间的空分隔符的必要性,如果您没有正确转义它,它可能会出现在您的消息中,并且可能导致严重的问题。

于 2013-07-03T20:00:27.763 回答