2009-04-01 17 views
6

Tôi muốn gửi một UIImage đến một máy chủ thông qua một ổ cắm.Làm thế nào để sử dụng tin nhắn viết của NSOutputStream?

a) Tôi mở 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) Tôi viết NSData để OutputStream sau mở hoàn và xử lý các lỗi nếu lỗi xảy ra.


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

Khi tôi chạy mã này, NSStreamEventOpenCompleted và NSStreamEventErrorOccurred là phương pháp ghi called.The NSOutputStream đã được gọi là thành công và tất cả các dữ liệu không phải là con số không. Nhưng sau khi dữ liệu được ghi vào oStream, eventCode sẽ thay đổi thành NSStreamEventErrorOccurred.

Vì vậy, tôi nghĩ rằng có lẽ đó không phải là cách chính xác để sử dụng [oStream write]. Cách chính xác để sử dụng tin nhắn này là gì? Tôi thấy thông báo này trả về NSInteger của -1073748088, điều gì có thể là vấn đề?

+0

[oStream streamError] cung cấp cho bạn những gì? – Chuck

+0

Thao tác không thể hoàn thành. Thời gian hoạt động ra –

Trả lời

13

Bạn chỉ nên ghi dữ liệu sau khi không gian có sẵn trong luồng đầu ra. Khi luồng kết thúc mở, nó không phải lúc nào cũng có sẵn không gian, vì vậy việc viết cho nó sẽ không hoạt động. Nếu bạn di chuyển cuộc gọi write tới trình xử lý NSStreamEventHasSpaceAvailable, nó sẽ thành công.

Ngoài ra, máy tính ở đầu kia của ổ cắm không có cách nào biết được độ dài của dữ liệu bạn đang gửi. Trừ khi bạn đang báo hiệu phần cuối của dữ liệu bằng cách đóng socket, bạn nên gửi dữ liệu một cách rõ ràng cùng với dữ liệu:

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

Một cảnh báo bật lên nói rằng: trong [oStream write: & length], chiều dài là loại con trỏ không tương thích. –

+0

Tôi đã cập nhật mã - chỉ cần truyền tới uint8_t * để loại bỏ cảnh báo. (Điều này về mặt kỹ thuật vi phạm các quy tắc bí danh nghiêm ngặt C99, nhưng trong thực tế điều này sẽ không thành vấn đề.) –

+0

Hiện tại, oStream vẫn gửi độ dài và dữ liệu đến máy chủ. Máy chủ vẫn không biết kết thúc dữ liệu. Tôi có thể thêm [oStream close] ở đâu? Hoặc tôi nên thêm mã vào phía máy chủ để đóng nó? –

Các vấn đề liên quan