2009-04-01 13 views
6

Deseo enviar un UIImage a un servidor a través de un socket.Cómo usar el mensaje de escritura de NSOutputStream?

a) que abra la 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) escribo NSData a OutputStream después de completado abierta y manejar el error si se produce un error.


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

Cuando ejecuta este código, NSStreamEventOpenCompleted y NSStreamEventErrorOccurred es el método de escritura de called.The NSOutputStream fue llamado con éxito y todos los datos no es nula. Pero después de que los datos se escriben en oStream, eventCode cambiará a NSStreamEventErrorOccurred.

Así que creo que quizás no sea la forma correcta de usar [oStream write]. ¿Cuál es la forma correcta de usar este mensaje, entonces? Me parece que este mensaje devuelve un NSInteger de -1073748088, ¿cuál podría ser el problema?

+0

¿Qué [ostream streamError] le dan? – Chuck

+0

No se pudo completar la operación. Tiempo de espera de operación –

Respuesta

13

Debe escribir los datos solo después de que haya espacio disponible en la secuencia de salida. Cuando la secuencia termina de abrirse, no siempre tiene espacio disponible inmediatamente, por lo que escribir en ella no funcionará. Si mueve la llamada write al controlador NSStreamEventHasSpaceAvailable, debería tener éxito.

Además, la computadora en el otro extremo del socket no tiene manera de saber la longitud de los datos que está enviando. A menos que esté señalando el final de los datos mediante el cierre de la toma de corriente, debe enviar explícitamente la longitud de datos junto con los datos:

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

Aparece una advertencia que dice: en [oStream write: & length], la longitud es un tipo de puntero incompatible. –

+0

He actualizado el código, simplemente transfórmelo en uint8_t * para eliminar la advertencia. (Esto infringe técnicamente las reglas de alias estrictas de C99, pero en la práctica esto no importará). –

+0

El oStream ahora sigue enviando la longitud y los datos al servidor. El servidor aún no sabe el final de los datos. ¿Dónde puedo agregar [oStream cerrar];? ¿O debería agregar código al lado del servidor para cerrarlo? –

Cuestiones relacionadas