к большему значению, которое добавляет ноль байтов. - Возможно, вы все равно захотите проверить максимальное значение, иначе система может попытаться выделить много ГБ, если поступят неверные данные.

я есть сервер, который отправляет мне сообщения по TCP, где первые 4 байта определяют длину остальной части сообщения. Так что мне нужно

1) прочитать 4 байта в UInt32 (работает) и сохранить его вbytes_expected

2) читатьbytes_expected байтов всообщение

Прямо сейчас мой код выглядит так:

private let inputStreamAccessQueue  = DispatchQueue(label: "SynchronizedInputStreamAccess")
func inputStreamHandler(_ event: Stream.Event) {
    switch event {
        case Stream.Event.hasBytesAvailable:
            self.handleInput()

        ...
    }
}
func handleInput() {
    // **QUESTION: Do I use this barrier wrong?**
    self.inputStreamAccessQueue.sync(flags: .barrier) {            
        guard let istr = self.inputStream else {
            log.error(self.buildLogMessage("InputStream is nil"))
            return
        }

        guard istr.hasBytesAvailable else {
            log.error(self.buildLogMessage("handleInput() called when inputstream has no bytes available"))
            return
        }

        let lengthbuffer = UnsafeMutablePointer<UInt8>.allocate(capacity: 4)
        defer { lengthbuffer.deallocate(capacity: 4) }
        let lenbytes_read = istr.read(lengthbuffer, maxLength: 4)

        guard lenbytes_read == 4 else {
            self.errorHandler(NetworkingError.InputError("Input Stream received \(lenbytes_read) (!=4) bytes"))
            return
        }

        let bytes_expected = Int(UnsafeRawPointer(lengthbuffer).load(as: UInt32.self).bigEndian)
        log.info(self.buildLogMessage("expect \(bytes_expected) bytes"))

        print("::DEBUG", call, "bytes_expected", bytes_expected)

        var message = ""
        var bytes_missing = bytes_expected
        while bytes_missing > 0 {
            //print("::DEBUG", call, "bytes_missing", bytes_missing)
            let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bytes_missing)
            let bytes_read = istr.read(buffer, maxLength: bytes_missing)

            print("::DEBUG", call, "bytes_read", bytes_read)

            guard bytes_read > 0 else {
                print("bytes_read not > 0: \(bytes_read)")
                return
            }

            guard bytes_read <= bytes_missing else {
                print("Read more bytes than expected. missing=\(bytes_missing), read=\(bytes_read)")
                return
            }

            guard let partial_message = String(bytesNoCopy: buffer, length: bytes_read, encoding: .utf8, freeWhenDone: true) else {
                log.error("ERROR WHEN READING")
                return
            }

            message = message + partial_message
            bytes_missing -= bytes_read
        }

        self.handleMessage(message)
    }
}

Моя проблема в том, что istr.read (buffer, maxLength: bytes_missing) иногда не читает все сообщения сразу, поэтому я зацикливаюсь, пока не прочитаю все, что хочу. Но я все еще вижу сбой моего приложения (редко), потому что handleInput () вызывается снова, пока еще выполняется другой вызов этого метода. В этом случае bytes_expected содержит случайные значения, и приложение вылетает из-за неправильного выделения памяти.

Я думал, что смогу избежать этого, используя барьер. Но, похоже, это не работает ... Я неправильно использую барьер?

Ответы на вопрос(2)

Ваш ответ на вопрос