с остальными данными.
ем сервере, основанном на TCP-сокете, я отправляю пакеты через поток, где пакеты состоят из заголовка, указывающего количество байтов в пакете, за которым следует это количество байтов. Для тех, кто знаком с Erlang, я просто устанавливаю параметр {package, 4}. Со стороны iOS у меня есть код, который выглядит следующим образом, при условии, что я хочу выяснить размер потока для этого сообщения:
[asyncSocket readDataToLength:4 withTimeout:-1 tag:HEADER_TAG];
Это работает нормально, и вызывается следующий метод обратного вызова:
onSocket:didReadData:withTag:
Я полагаю, что следующий логический шаг - выяснить размер потока, и я делаю это с помощью:
UInt32 readLength;
[data getBytes:&readLength length:4];
readLength = ntohl(readLength);
После жесткого кодирования строки из 12 байтов на стороне сервера readLength действительно читает также и на клиенте 12, так что пока все хорошо. Я продолжаю со следующим:
[sock readDataToLength:readLength withTimeout:1 tag:MESSAGE_TAG];
На данный момент, хотя обратный вызовonSocket:didReadData:withTag:
больше не вызывается. Вместо этого происходят тайм-ауты при чтении, возможно, потому что я не обработал чтение должным образом, этот метод делегата вызывается:
- (NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length
итак, сервер отправляет 16 байтов, 4-байтовый заголовок и 12-байтовый двоичный поток.
Я уверен, что ошибка в том, как я использую CocoaAsyncSocket. Как правильно читать остаток потока после того, как я выясню его размер?
** ОБНОВИТЬ **
Я изменил мой клиент, и теперь он работает. Проблема в том, что я не понимаю смысла readDataToLength с новым решением. Вот что я изменил в своем первоначальном прочтении:
[socket readDataWithTimeout:-1 tag:HEADER_TAG];
Теперь в моем обратном вызове я просто делаю следующее:
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
if (tag == HEADER_TAG) {
UInt32 readLength;
[data getBytes:&readLength length:4];
readLength = ntohl(readLength);
int offset = 4;
NSRange range = NSMakeRange(offset, readLength);
char buffer[readLength];
[data getBytes:&buffer range:range];
NSLog(@"buffer %s", buffer);
//[sock readDataToLength:readLength withTimeout:1 tag:MESSAGE_TAG];
} else if (tag == MESSAGE_TAG) {
//[sock readDataToLength:4 withTimeout:1 tag:HEADER_TAG];
}
}
Так что все приходит как единое целое, атомная нагрузка. Возможно, это из-за того, как работает Erlang {package, 4}. Я надеюсь, что это так. Иначе какой смысл в readDataToLength? нет способа заранее узнать длину сообщения на клиенте, так в чем же хороший вариант использования этого метода?