我正在将CocoaAsyncSocket用于iOS项目。我试图通过异步接口读取VarInts。问题不像String这样的东西,我可以在前面加上长度,我不知道varint的长度。它需要一次处理一个字节,但由于每个读取操作都是异步的,因此其他读取调用可能已在其间排队。
我考虑读入缓冲区然后处理它,比如读取5个字节(varint-32的最大长度),然后推回额外的字节,但如果varint只有4个字节而且我可能会不必要地挂起等待第5个字节可用。
我该怎么做?另外,我不能改变另一端的协议,使用固定大小的整数。
这是Josh要求的一段代码
- (void)readByte:(void (^)(int8_t))onComplete {
NSUInteger size = 1;
int32_t tag = OSAtomicAdd32(1, &_nextTag);
dispatch_async(self.dispatchQueue, ^{
[self.onCompleteHandlers setObject:(^void (NSData* data) {
int8_t x = 0;
[data getBytes:&x length:size];
onComplete(x);
}) forKey:[NSNumber numberWithInteger:((NSInteger) tag)]];
[self.socket readDataToLength:size withTimeout:-1 tag:tag];
});
}
回调保存在字典中,该字典在委托方法socket: didReadData: withTag
中使用。
假设我正逐字节地读取VarInt:
我可以想象使用一个标志来指示我是否处于多部分读取,以及一个队列来保存应该在多部分读取之后执行的读取,并且我已经开始编写它但是它非常混乱。只是想知道是否有标准/推荐/更好的方法来解决这个问题。
答案 0 :(得分:1)
简而言之,有4种方法可以知道从套接字中读取多少...
Content-Length
标题...仅在整个请求可以在发送正文之前放在一起时才有效。\r\n\r\n
这些都有问题,我可能会在你的情况下使用现有的协议。
当然这样做有开销,你可能会发现你不想使用任何应用程序级别的东西,你的请求可能是这样的:
client>"doMath(2+5)\0"
server>"(7)\0"
但很难具体回答你的一般性问题。
修改强>
所以我对varint base-128问题进行了一点研究,我认为实际上只有超时或关闭连接的服务器才能正常工作,如果你在TCP级写这些是非常糟糕的......