Что означает свойство hasSpaceAvailable в NSOutputStream?
Я пытаюсь обернуть голову вокруг логики позади hasSpaceAvailable
на NSOutputStream.
В моем приложении я отправляю большие объемы данных (100 МБ), разбитые на куски по 4080 байт (жесткий предел), через CFSocket, управляемый потоками NSInput/output.
Когда я начинаю писать данные, примерно четверть пути hasSpaceAvailable
вдруг становится NO
и поэтому я добавляю данные в очередь. Однако, если я проигнорирую это и попытаюсь записать данные в любом случае, запись будет работать как возвращаемое значение write:maxLength:
соответствует параметру maxLength (4080).
Для чего в выходном потоке есть место? Насколько я могу судить, при использовании сокетов UNIX/Berkley нет никакой логики, позволяющей определить, можно ли записать сокет, просто напишите и определите, все ли данные были записаны.
В документации по недвижимости говорится:
Логическое значение, указывающее, можно ли записать получатель. (Только для чтения)
YES
если получатель может быть записан или если попытаться выполнить запись, чтобы определить, доступно ли место,NO
иначе.
В моем примере, где я вижу НЕТ, какой фактор вызывает этот результат, когда я все еще могу записать в этот сокет.
1 ответ
Я думаю, что свойство hasSpaceAvailable просто возвращает YES, если поток отправил событие потока "space available" с момента последнего вызова метода write. Вы не должны опрашивать это свойство, и, возможно, оно даже не должно существовать. Вместо этого вы должны дождаться события потока в выходном потоке, которое говорит, что вместо этого доступно пространство для записи.
Когда происходит это потоковое событие, это означает, что очередь исходящих пакетов имеет как минимум на один байт меньше максимального числа байтов, которое сокет сконфигурирован, чтобы позволить вам поставить в очередь. Другими словами, системный вызов send() или write() в сокете гарантированно записывает хотя бы один байт без блокировки, а сокет гарантированно находится в неблокирующем режиме.
Обратите внимание, что после записи данных поток немедленно отправит другое доступное пространство, если буфер потока может принять больше данных (или после того, как он отправил некоторые данные, если буфер заполнен).