检测可以写入NSOutputStream的字节数

时间:2016-03-14 17:26:57

标签: ios objective-c swift macos nsstream

我试图实现的基本问题:

我有两个流。 NSInputStreamNSOutputStream。 现在我想从输入过程中获取一些数据(添加一些帧对它们进行编码等等)并传递给输出。到目前为止一切都很好。

实际问题

问题是NSOutputStream API - write:maxLength:可以返回写入的实际字节数。该值可以与传递的长度不同。这是一个问题,因为它需要创建额外的逻辑来维护某种缓冲区。 我想避免这种情况。我想现在输出流将接受多少字节而不进行缓冲,这样我就可以计算出我应该从输入流中读取多少数据(我将添加一些帧和编码)。 我不想保留额外的缓冲区。

输出流与TCP套接字相关联,输入流可以与任何类型的资源相关联。

2 个答案:

答案 0 :(得分:1)

This is the apple implementation问题:

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode
{
    switch(eventCode) {
        case NSStreamEventHasSpaceAvailable:
        {
            uint8_t *readBytes = (uint8_t *)[_data mutableBytes];
            readBytes += byteIndex; // instance variable to move pointer
            int data_len = [_data length];
            unsigned int len = ((data_len - byteIndex >= 1024) ?
                1024 : (data_len-byteIndex));
            uint8_t buf[len];
            (void)memcpy(buf, readBytes, len);
            len = [stream write:(const uint8_t *)buf maxLength:len];
            byteIndex += len;
            break;
        }
        // continued ...
    }
}

在此实现中,一次写入1024字节的块。

并提供了一条说明:

  

对于一次写入多少字节没有确切的指导。   虽然可以将所有数据写入流中   事件,这取决于外部因素,如行为   内核以及设备和套接字特性。最好的方法是   使用一些合理的缓冲区大小,例如512字节,1千字节(如   在上面的例子中),或页面大小(4千字节)。

如上所述,它取决于另一方。不知道是否可以通过调查接收器来解决这个问题。但是,建议一次写入的大小可能会降低某些字节不会被写入的可能性。应该实施这种逻辑。

答案 1 :(得分:0)

你必须缓冲。在进行尝试之前,流无法预测可以写入的内容。但是你可以通过以下方式保持缓冲区尽可能小:(a)尝试一次写入更少的数据,以及(b)仅缓冲先前尝试中未写入的数据。

这种安排的结果是以空间换取速度。将一个字节缓冲区视为简并情况。