Метод делегата AsyncSocket вызван неправильно?

Я передаю достаточно большое изображение по локальной сети с iPhone на Mac, используя класс AsyncSocket. В заголовке объявлен метод делегата didReadData, как показано ниже:

/**
 * Called when a socket has completed reading the requested data into memory.
 * Not called if there is an error.
**/
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;

В нем говорится, что этот метод будет вызван, когда сокет завершит чтение данных. Однако этот метод вызывается много раз, каждый раз увеличивая длину данных. Как я должен узнать, когда загрузка завершена? Я должен отправить длину данных в первых нескольких байтах?


person Jonathan.    schedule 21.04.2011    source источник


Ответы (1)


Этот метод делегата действительно будет вызываться, когда сокет завершит чтение данных. Недостающая часть уравнения сообщает AsyncSocket когда полученные данные будут завершены. У него нет понимания данных, которые вы пытаетесь получить, вы должны сообщить ему об этом, как вы упомянули в своем последнем вопросе.

Вот где AsyncSocket действительно сияет. Вы действительно можете отправить изображение с префиксом его длины и позволить классу творить чудеса. Ваш код будет выглядеть примерно так:

[sock readDataToData:[AsyncSocket CRLFData] withTimeout:0 tag:kLengthTag];

В вашем методе делегата:

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    if (tag == kLengthTag) {
        NSUInteger length = /* read length out of nsdata */;
        [sock readDataToLength:length withTimeout:0 tag:kImageTag];
    } else if (tag == kImageTag) {
        /* hurray, you have your image! */
    }
}

Конечно, если вы передаете достаточно большие изображения, вы можете отслеживать свой прогресс. Для этого существует метод экземпляра -[AsyncSocket progressOfReadReturningTag:bytesDone:total:]. Также есть метод делегата -[id<AsyncSocketDelegate> onSocket:didReadPartialDataOfLength:tag:].

person Sedate Alien    schedule 22.04.2011
comment
Это было бы здорово, если бы это работало, поскольку при реализации этого didReadData только иногда вызывается для длины и никогда не вызывается для изображения. - person Jonathan.; 22.04.2011
comment
По какой-то сумасшедшей причине длина должна быть int, а не NSUInteger, хотя я использовал NSUInteger везде, потому что это то, что использует NSData. - person Jonathan.; 22.04.2011
comment
Возможно, вы могли бы поделиться с нами примером кода. Чрезвычайно маловероятно, что использование NSUInteger (определение типа для long или int, в зависимости от вашей платформы) является проблемой; это, скорее всего, проблема с вашим анализом в другом месте. - person Sedate Alien; 23.04.2011
comment
Это не сработало, поэтому я попытался установить длину на 5. И постепенно увеличивался, пока не достиг фактической длины, если данные передавались, и все работало отлично. Видя, что длина прямо в коде - это int, я изменил тип на int, и это сработало. Изменил его обратно на NSUInteger, и это не сработало. - person Jonathan.; 23.04.2011