2009-04-01 12 views
6

Desidero inviare un UIImage a un server tramite un socket.Come utilizzare il messaggio di scrittura di NSOutputStream?

a) apro l'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) Scrivo NSData a OutputStream dopo aperto completato e gestire l'errore se si verifica un errore.


- (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"); 
} 

Quando ho eseguito questo codice, NSStreamEventOpenCompleted e NSStreamEventErrorOccurred è il metodo di scrittura di called.The NSOutputStream è stato chiamato con successo e tutti i dati non è pari a zero. Ma dopo che i dati sono stati scritti su oStream, l'eventCode cambierà in NSStreamEventErrorOccurred.

Quindi penso che forse non è il modo corretto di usare [oStream write]. Qual è il modo corretto di usare questo messaggio allora? Trovo che questo messaggio restituisca un NSInteger di -1073748088, quale potrebbe essere il problema?

+0

Cosa [ostream streamError] ti danno? – Chuck

+0

L'operazione non può essere completata. Timeout operativo –

risposta

13

Si dovrebbero scrivere i dati solo dopo che lo spazio è diventato disponibile nel flusso di output. Quando lo stream termina l'apertura, non sempre ha immediatamente spazio disponibile, quindi la scrittura non funzionerà. Se si sposta la chiamata write al gestore NSStreamEventHasSpaceAvailable, dovrebbe riuscire.

Inoltre, il computer all'altra estremità del socket non ha modo di conoscere la lunghezza dei dati inviati. A meno che non si sta segnalando la fine dei dati chiudendo la presa, è necessario inviare in modo esplicito la lunghezza dei dati insieme ai dati:

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

Viene visualizzato un avviso che dice: in [oStream write: & length], la lunghezza è un tipo di puntatore incompatibile. –

+0

Ho aggiornato il codice - appena lanciato su uint8_t * per eliminare l'avviso. (Questo tecnicamente viola le rigide regole di aliasing C99, ma in pratica non importa.) –

+0

OStream ora continua a inviare la lunghezza e i dati al server. Il server non conosce ancora la fine dei dati. Dove posso aggiungere [oStream close] ;? O dovrei aggiungere codice al lato server per chiuderlo? –

Problemi correlati