何时关闭NSOutputStream?

时间:2009-04-03 07:03:49

标签: objective-c cocoa sockets stream

我想通过套接字将UIImage的数据发送到服务器,所以我:

a)打开NSOutputStream


- (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)当空间可用时将数据写入oStream


- (void) stream: (NSStream *) stream handleEvent: (NSStreamEvent) eventCode
{
switch(eventCode)
    {
    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]);

                    [oStream write:(uint8_t *)&length maxLength:4];
                    [oStream write:[data bytes] maxLength:length];
            }
    }
    break;
}

问题是数据一次又一次地写入oSream。如何在发送所有数据时停止它?

我在Image数据之前发送数据的长度,以便让服务器知道它何时到达终点。我是否必须更改服务器端的代码才能在到达结尾时关闭套接字?我在哪里可以添加[oStream close]来关闭客户端的oStream?

1 个答案:

答案 0 :(得分:5)

  

问题是数据一次又一次地写入oSream。如何在发送所有数据时停止它?

看,这是被动语态思考的危险。用主动语态重新提问:

  

问题是数据一次又一次地写入oSream。我发送所有数据后如何阻止它?

你几乎回答了自己的问题。

问题的很大一部分是你的HasSpaceAvailable处理程序。这是你正在做的事情:

  1. 创建图像的完整JPEG表示(每次)
  2. 发送表示的长度(每次)
  3. 发送表示的第一部分(每次)
  4. 这是三个问题,你需要解决这三个问题。

    1. 创建一次JPEG表示。
    2. 仅发送一次表示的长度。
    3. 跟踪您已发送的内容,并仅发送您尚未发送的内容的第一部分。
    4. 要完成所有这三项操作,请将长度放入NSMutableData并将JPEG表示附加到其中。然后,保留此新数据对象,并为字节指针和剩余长度添加其他实例变量。在进入HasSpaceAvailable状态之前,您将完成所有这些

      然后,当你到达HasSpaceAvailable时,不要单独发送长度,因为你已将它放入数据对象中。您只需要从指针实例变量发送字节,剩余长度为最大长度。在检查发送的字节数不是0或-1(参见the documentation)之后,将其添加到指针并从剩余长度中减去它。

      当剩余长度达到零时,您已发送所有内容。假设您不想使用某些内容跟踪JPEG数据,则可以关闭该流。