2016-06-16 8 views
1

В моем приложении я использую NSStreams для связи с клиентским сервером. В методе delegate в случае hasbytesAvailable, когда я читаю данные его возвращение нулевойЧтение данных NSinputstream возвращает нулевое значение?

Корпус: когда длина 4096, то прочитанная терпит неудачу и возвращает ноль; Значит, когда длина равна размеру буфера, которую он не читает, даже если я поместил максимальную длину до 4000 и размер буфера до 4096, тогда также, когда 4000 байт считываются с ошибкой. что делать?

Вот код:.

case NSStreamEventHasBytesAvailable: 

    if (aStream == inputStream) { 
      uint8_t buffer[4096]; 
      int len; 
      while ([inputStream hasBytesAvailable]) {      
       len = (int)[inputStream read:buffer maxLength:sizeof(buffer)]; 
       NSLog(@"\nThe length is -- %d\n",len); 
        if (len > 0) { 
          NSData *data = [[NSData alloc] initWithBytes:buffer length:len]; 
          output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
           // output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding];        
           } 
        } 
       }   

     NSLog(@"\n\n%@\n\n",output); 
+0

Я не вижу каких-либо сообщений об ошибках, так что гадать. – Droppy

+0

Я не знаю, но может ли это быть связано с этим: http://stackoverflow.com/questions/36894972/why-doesnt-cast-work-from-nsdata-to-string-swift/? Я имею в виду, что когда буфер заполнен (длина - размер буфера), это означает, что есть большая вероятность, что это только часть данных? – Larme

+0

@Droppy, ошибка не возникает, но она возвращает нуль в случае –

ответ

0

Я думаю, что код абсолютно прав, и он должен читать данные, может быть, после того, как вы прочитали 4096 байт, может быть еще несколько доступных байтов, и цикл продолжается, и вы снова инициализируете выходную переменную. Таким образом, вы можете пропустите его.

Используйте следующий фрагмент кода:

if (aStream == inputStream) { 
        uint8_t buffer[4096]; 
        int len; 
        NSString* tempOutput = @""; 

        while ([inputStream hasBytesAvailable]) { 

         len = (int)[inputStream read:buffer maxLength:sizeof(buffer)]; 
         NSLog(@"\nThe length is -- %d\n",len); 
         if (len > 0) { 
          NSData *data = [[NSData alloc] initWithBytes:buffer length:len]; 
          output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
          tempOutput = [tempOutput stringByAppendingString:output]; 
           // output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding]; 

           } 
        } 
       output = tempOutput; 
       } 
+0

Это очень наивный подход. – Droppy

+0

может быть, но он может служить цели –

+0

Я бы по крайней мере добавлял 'output' в' tempOutput', если 'output' не равен нулю, а если он равен нулю, добавьте данные. – Larme

1

Считывание данных из сети связи не всегда будут получены в одних и тех же размера куски он был направлен в Это означает, что необходимо приемнику:

  1. Знайте, сколько данных ожидать в сообщении.
  2. Помните, что все оставшиеся данные из текущего сообщения совпадают с следующим сообщением.

Одним из самых простых способов сделать это правильно является префикс сообщения с байтом-счетчиком, а затем только попытка считывать столько данных из сетевого подключения. Это оставляет любые оставшиеся данные в «сетевом буфере» до тех пор, пока клиент этого не захочет.

Ваш код получает строку, которая будет NUL, - это значит, что вам нужно прочитать данные в кусках фиксированного размера, проверить каждый байт, пока не найдете конец строки, а затем соедините куски, прежде чем преобразовать его в строку. Затем вам нужно запомнить любые «оставшиеся» данные для следующего сообщения. Сложный материал, а?

Я бы пошел с префиксом размера сообщения, так как это то, что делают все остальные.