如何使用NSOutputStream写消息?

时间:2009-04-01 01:38:57

标签: objective-c cocoa sockets stream

我想通过套接字将UIImage发送到服务器。

a)我打开输出流:


- (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)我在打开完成后将NSData写入outputstream并在发生错误时处理错误。


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

当我运行此代码时,将调用NSStreamEventOpenCompleted和NSStreamEventErrorOccurred。成功调用NSOutputStream的write方法,并且所有数据都不是nil。但是在将数据写入oStream之后,eventCode将更改为NSStreamEventErrorOccurred。

所以我想也许这不是使用[oStream write]的正确方法。那么使用此消息的正确方法是什么?我发现这条消息返回一个-1073748088的NSInteger,可能是什么问题?

1 个答案:

答案 0 :(得分:13)

只有在输出流中有空间可用后才应该写入数据。当流完成打开时,它并不总是立即有可用空间,因此写入它将不起作用。如果您将write调用移至NSStreamEventHasSpaceAvailable处理程序,则应该会成功。

此外,套接字另一端的计算机无法知道您发送的数据的长度。除非您通过关闭套接字来发出数据结束信号,否则您应该明确地将数据长度与数据一起发送:

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;
}