Вопрос интерпретации документации IOCP - неоднозначность владения буфером

Поскольку я не являюсь носителем английского языка, мне может что-то не хватать, так что, возможно, кто-то здесь знает лучше меня.

Взято из документации WSASend в MSDN :

lpBuffers [в]

Указатель на массив структур WSABUF. Каждая структура WSABUF содержит указатель на буфер и длину буфера в байтах. Для приложения Winsock после вызова функции WSASend система владеет этими буферами, и приложение может не получить к ним доступ. Этот массив должен оставаться действительным в течение всей операции отправки.

Хорошо, вы видите жирный текст? Непонятное место!

Я могу придумать два перевода для этой строки (может быть что-то еще, вы называете это):
Перевод 1 - «буферы» относятся к структуре OVERLAPPED, которую я передаю этой функции при ее вызове. Я могу повторно использовать объект снова только после получения уведомления о его завершении.
Перевод 2 - «буферы» относятся к фактическим буферам, с данными, которые я отправляю. Если объект WSABUF указывает на один буфер, то я не могу коснуться этого буфера, пока операция не будет завершена.

Может ли кто-нибудь сказать, как правильно интерпретировать эту строку?

И ... Если ответ второй - как бы вы его разрешили?
Потому что для меня это означает, что для каждого отправляемого мной данных / буфера я должен сохранять их копию у отправителя сторона - таким образом, имея МНОГО «ожидающих» буферов (разных размеров) в приложении с высоким трафиком, что действительно повредит «масштабируемости».

Утверждение 1:
В дополнение к предыдущему абзацу («И ....») я думал, что IOCP копирует данные, которые должны быть отправлены, в свой собственный буфер и отправляет оттуда, если вы не установите SO_SNDBUF до нуля.

Утверждение 2:
Я использую буферы, выделенные стеком (вы знаете, что-то вроде char cBuff[1024]; в теле функции - если перевод основного вопроса является вторым вариантом (т.е. буферы должны оставаться такими, как они есть до завершения отправки), тогда ... это действительно сильно портит ситуацию! Можете ли вы придумать способ решить эту проблему? (Я знаю, я спросил об этом другими словами выше).


person Poni    schedule 12.06.2010    source источник


Ответы (1)


Ответ заключается в том, что перекрывающаяся структура и сам буфер данных не могут быть повторно использованы или освобождены до тех пор, пока операция не завершится.

Это связано с тем, что операция завершается асинхронно, поэтому даже если данные в конечном итоге копируются в принадлежащие операционной системе буферы в стеке TCP / IP, это может произойти только через некоторое время в будущем, и вы получите уведомление о том, когда произойдет завершение записи. Обратите внимание, что с завершением записи они могут быть отложены на удивительное время, если вы отправляете отправку без явного управления потоком и полагаетесь на стек TCP для управления потоком за вас (см. Здесь: некоторые ПЕРЕПЛАТЫ с использованием WSASend не возвращаются вовремя с помощью GetQueuedCompletionStatus? ) ...

Вы не можете использовать выделенные стеком буферы, если вы не поместите событие в перекрывающуюся структуру и не заблокируете его до завершения асинхронной операции; в этом нет особого смысла, поскольку вы увеличиваете сложность по сравнению с обычным блокирующим вызовом, и вы не выиграете много, выполнив асинхронный вызов, а затем ожидая его.

В моей серверной структуре IOCP (которую вы можете бесплатно получить по адресу здесь) Я использую динамически выделяемые буферы, которые включают структуру OVERLAPPED и подсчитывают ссылки. Это означает, что очистка (в моем случае они возвращаются в пул для повторного использования) происходит, когда происходит завершение и освобождается ссылка. Это также означает, что вы можете продолжить использование буфера после операции, и очистка по-прежнему проста.

См. Также здесь: I / O Порт завершения, как освободить для контекста сокета и контекста ввода-вывода?

person Len Holgate    schedule 13.06.2010
comment
Большое спасибо за ответ, Лен, получение его от тебя очень много значит для меня! Я понимаю общую идею, но не могу перейти к конкретным вопросам, описанным в stackoverflow.com/questions/3034047/. - person Poni; 14.06.2010
comment
Помечено как ответ, так как ваш ответ - это ответ в конце дня. Еще раз спасибо! - person Poni; 14.06.2010