2009-04-01 8 views
6

Chcę wysłać UIImage do serwera przez gniazdo.Jak korzystać z wiadomości typu NSOutputStream?

a) Otwieram OutputStream:


- (IBAction)send:(id)sender { 
    NSURL *website = [NSURL URLWithString:str_IP]; 
    NSHost *host = [NSHost hostWithName:[website host]]; 
    [NSStream getStreamsToHost:host port:1100 inputStream:nil outputStream:&oStream]; 
    [oStream retain]; 
    [oStream setDelegate:self]; 
    [oStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    [oStream open]; 
} 

b) piszę NSData do OutputStream po otwarte zakończona i obsługi błędu w przypadku wystąpienia błędu.


- (void) stream: (NSStream *) stream handleEvent: (NSStreamEvent) eventCode 
{ 
    //printf("EVENT: Start.\n"); 

    switch(eventCode) 
    { 
      case NSStreamEventOpenCompleted: 
      { 
       //printf("EVENT: Open completed.\n"); 

       if(stream == oStream) 
        { 
         //printf("Sending...\n"); 
         NSData *data = UIImageJPEGRepresentation(drawImage.image, 90); 
         NSInteger x = [oStream write:[data bytes] maxLength:[data length]]; 
        } 

       break; 
      } 
      case NSStreamEventEndEncountered: 
      { 
       //printf("EVENT: End encountered.\n"); 
       break; 
      } 
      case NSStreamEventHasSpaceAvailable: 
      { 
       //printf("EVENT: Has space available.\n"); 
       break; 
      } 
      case NSStreamEventHasBytesAvailable: 
      { 
       //printf("EVENT: Has bytes available.\n"); 
       break; 
      } 
      case NSStreamEventErrorOccurred: 
      { 
       UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error Occurred"  
                   message:nil 
                   delegate:nil    
                 cancelButtonTitle:@"OK"    
                 otherButtonTitles:nil];     
       [alert show]; 
       [alert release]; 
       break; 
      } 
      case NSStreamEventNone: 
      { 
       //printf("EVENT: None.\n"); 
       break; 
      } 
    } 

    //printf("EVENT: End.\n"); 
} 

Kiedy uruchomić ten kod, NSStreamEventOpenCompleted i NSStreamEventErrorOccurred jest metoda zapisu called.The NSOutputStream nazywała się pomyślnie i wszystkie dane, nie jest zerowa. Ale po zapisaniu danych do oStream, eventCode zmieni się na NSStreamEventErrorOccurred.

Myślę więc, że może nie jest to właściwy sposób użycia [napisu oStream]. Jaki jest zatem właściwy sposób korzystania z tego komunikatu? Uważam, że ten komunikat zwraca NSInteger z -1073748088, co może być problem?

+0

Co [ostream streamError] dać? – Chuck

+0

Operacja nie mogła zostać zakończona. Czas zadziałania –

Odpowiedz

13

Powinieneś zapisywać dane tylko wtedy, gdy wolne miejsce stanie się dostępne w strumieniu wyjściowym. Kiedy strumień się kończy, nie zawsze jest dostępne wolne miejsce, więc pisanie do niego nie zadziała. Jeśli przeniesiesz wywołanie write do obsługi obsługi NSStreamEventHasSpaceAvailable, powinno się powieść.

Również komputer po drugiej stronie gniazda nie ma możliwości sprawdzenia długości przesyłanych danych. Jeśli nie jesteś sygnalizując koniec ustalonego danych przez zamknięcie gniazda, należy wyraźnie wysłać długość danych wraz z danymi:

case NSStreamEventHasSpaceAvailable: 
{ 
    if(stream == oStream) 
    { 
     NSData *data = UIImageJPEGRepresentation(drawImage.image, 90); 
     // Convert from host to network endianness 
     uint32_t length = (uint32_t)htonl([data length]); 
     // Don't forget to check the return value of 'write' 
     [oStream write:(uint8_t *)&length maxLength:4]; 
     [oStream write:[data bytes] maxLength:length]; 
    } 
    break; 
} 
+1

Pojawia się ostrzeżenie, że: w [oStream write: & length], length jest niekompatybilnym typem wskaźnika. –

+0

Zaktualizowałem kod - wystarczy rzucić na uint8_t *, aby pozbyć się ostrzeżenia. (To technicznie narusza surowe zasady aliasingu C99, ale w praktyce nie będzie to miało znaczenia.) –

+0

OStream wysyła teraz długość i dane do serwera. Serwer nadal nie zna końca danych. Gdzie mogę dodać [oStream close] ;? Czy powinienem dodać kod po stronie serwera, aby go zamknąć? –