GCDAsyncSocket 标记参数

3
我想知道如何在诸如方法中使用标记参数。
readDataWithTimeout: tag:
writeData: tag:

如果我想使用标签来识别数据包的类型会发生什么?例如,如果我说tag == 2表示数据包是来自客户端的消息,tag == 1表示数据包是来自服务器的消息... 如果这样做可以,那我需要多次调用readData:withTag:(每个不同的标签都需要调用一次)吗?
[readDataWithTimeout:-1 tag:1];
[readDataWithTimeout:-1 tag:2];

有没有一种方法可以说:“读取每个数据而不关心标签”,然后在didReadData: withTag:方法中根据标签处理数据?
1个回答

6
我认为您对标签概念有些误解。读取操作并不是在说“读取已被标记为2的数据”,而是在说“从网络中读取下一个数据,并将其标记为2以便日后查阅”。
标签永远不会被发送到网络中 - 服务器没有标记数据并将其发送给客户端进行读取。它只是一个完全可选的概念,仅用于区分本地操作。换句话说,正在被读取的数据没有标签。标签是您为读取操作分配的东西,以便您可以在操作完成后识别它。
例如,假设您正在按照标题和负载的方式读取数据。您可以使用标签来区分标题读取和负载读取:
const NSInteger kHeaderTag = 1;
const NSInteger kPayloadTag = 2;

// Assume you know to expect a header, so tag the read operation as such.
[self readDataWithTimeout:-1 tag:kHeaderTag];

// Next assume you know to expect a payload, so tag the read operation as such.
[self readDataWithTimeout:-1 tag:kPayloadTag];

那么之后你就可以辨认它了...

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    if (tag == kHeaderTag)
    {
        // Handle header
    }
    else if (tag == kPayloadTag)
    {
        // Handle payload
    }
}

谢谢,我仔细阅读了文档并理解了。为了识别数据包的“类型”,我决定将所有数据都封装在NSDictionary中,并使用一个键来标识数据包。例如,当我读取NSData时,我会提取键(NSString),并根据键来处理数据包。这是一个好的做法吗?还是我应该改变我的方法? - rmonjo
@user1437126 所以你正在对字典和数据进行序列化?听起来很好。 - Matt Wilding
是的,这就是我的工作。整个下午测试了这个解决方案,非常高效和干净。再次感谢您的回复。 - rmonjo
1
在 GCDAsyncSocket 的文档中,确实需要澄清标签不会通过网络发送。太好了,我浪费了很多时间设置服务器来识别客户端发送的标签。你可能为我节省了更多的时间。 - sudo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接