-Есть две функции: WSASend и GetQueuedCompletionStatus.
Обе функции одним из параметров принимают структуру WSAOVERLAPPED, в которую что то там записывают.
В случае с WSASend-GetQueuedCompletionStatus в WSAOVERLAPPED идет запись в параметр WSAOVERLAPPED.InternalHigh — то кол-во байт, которое якобы отправлено на данный момент.
1)И вот вопрос: Получается, что приходится для одной и той же операции создавать две структуру и два раза ее передавать, но, если WSASend используется совместно с портами завершения, то информацию пользователь же получает из очереди порта завершения посредством функции GetQueuedCompletionStatus куда и передает дублированную структуру WSAOVERLAPPED. Зачем же тогда две структуры передавать ?
2)И позвольте второй вопрос: у функции GetQueuedCompletionStatus — второй параметр это:
Указатель на переменную, которая получает количество байтов, переданных в завершенной операции ввода-вывода.
и соответственно, как уже писал выше 4ый параметр — это структура WSAOVERLAPPED, которая так в один из своих полей получает — "количество байтов, переданных в завершенной операции ввода-вывода.".
Зачем тогда нужен второй параметр ? Или зачем тогда передавать WSAOVERLAPPED, если есть второй параметр, куда GetQueuedCompletionStatus и так запишет нужное кол-во байт ?
Здравствуйте, reversecode, Вы писали:
R>оверлапед нужно для много поточной архитектуры R>считайте оверлапед как контекст R>который передается в wsasend R>а получает их GetQueuedCompletionStatus
Я это понимаю. Но, не понимаю зачем дублировать параметры, которые по сути возвращают одно и тоже значение.
A pointer to the number, in bytes, sent by this call if the I/O operation completes immediately.
Use NULL for this parameter if the lpOverlapped parameter is not NULL to avoid potentially erroneous results. This parameter can be NULL only if the lpOverlapped parameter is not NULL.
O>1)И вот вопрос: Получается, что приходится для одной и той же операции создавать две структуру и два раза ее передавать, но, если WSASend используется совместно с портами завершения, то информацию пользователь же получает из очереди порта завершения посредством функции GetQueuedCompletionStatus куда и передает дублированную структуру WSAOVERLAPPED. Зачем же тогда две структуры передавать ?
GetQueuedCompletionStatus _возвращает_ вам указатель на структуру LPOVERLAPPED, ранее переданную в WSASend. (ведь ее аргумент lpOverlapped — это двойной указатель).
На всякий случай отвечу на вопрос типа 'а зачем он мне его возвращает я ведь его сам знаю?' — затем что если вы запустили 100500 параллельных WSASend, по этому указателю вы сможете понять к какому именно из них относится этот результат.
O>В случае с WSASend-GetQueuedCompletionStatus в WSAOVERLAPPED идет запись в параметр WSAOVERLAPPED.InternalHigh — то кол-во байт, которое якобы отправлено на данный момент. O>2)И позвольте второй вопрос: у функции GetQueuedCompletionStatus — второй параметр это: O>
O>Указатель на переменную, которая получает количество байтов, переданных в завершенной операции ввода-вывода.
Потому что внутреннее назначение полей WSAOVERLAPPED — недокументированные вещи напрямую их ковырять не стоит. GetQueuedCompletionStatus просто выковыривает вам оттуда нужный вам параметр документированным способом.
Как много веселых ребят, и все делают велосипед...
Согласен, но есть маленькое замечаение, вдруг кто не в курсе по поводу вот этого:
O>Потому что внутреннее назначение полей WSAOVERLAPPED — недокументированные вещи напрямую их ковырять не стоит. GetQueuedCompletionStatus просто выковыривает вам оттуда нужный вам параметр документированным способом.
Толи начиная с XP, толи с 7-ки Microsoft понял что API в таком виде устоялся и уже, по сути, прибит гвоздями низкоуровневой реализации и данные поля стали документированными. Читал об этом где-то в статьях самого Microsoft в MSDN, но не могу сейчас найти. Вот косвенное подтверждение.
InternalHigh When an asynchronous I/O request completes, this member holds the number of bytes transferred.
When first designing the OVERLAPPED structure, Microsoft decided not to document the Internal and InternalHigh members (which explains their names). As time went on, Microsoft realized that the information contained in these members would be useful to developers, so it documented them. However, Microsoft didn’t change the names of the members because the operating system source code referenced them frequently, and Microsoft didn’t want to modify the code.
O>На всякий случай отвечу на вопрос типа 'а зачем он мне его возвращает я ведь его сам знаю?' — затем что если вы запустили 100500 параллельных WSASend, по этому указателю вы сможете понять к какому именно из них относится этот результат.
Вообще соответствие пакета, который мы достали из очереди с помощью GetQueuedCompletionStatus — и одного из 100500 параллельных WSASend — идентифицируется через CompletionKey.
O>Потому что внутреннее назначение полей WSAOVERLAPPED — недокументированные вещи напрямую их ковырять не стоит. GetQueuedCompletionStatus просто выковыривает вам оттуда нужный вам параметр документированным способом.
А поэтому вопрос остается, зачем тогда передавать адрес указателя на структуру WSAOVERLAPPED, чтобы в итоге получить ее адрес, если Вы сами говорите, что "внутреннее назначение полей WSAOVERLAPPED — недокументированные вещи напрямую их ковырять не стоит" и идентификация пакета и вызова WSASend определяется через CompletionKey, а кол-во отравленных или принятых байт определяется через второй параметр функции GetQueuedCompletionStatus.
То есть Вы противоречите сами себе получается ?
O>>На всякий случай отвечу на вопрос типа 'а зачем он мне его возвращает я ведь его сам знаю?' — затем что если вы запустили 100500 параллельных WSASend, по этому указателю вы сможете понять к какому именно из них относится этот результат. O>Вообще соответствие пакета, который мы достали из очереди с помощью GetQueuedCompletionStatus — и одного из 100500 параллельных WSASend — идентифицируется через CompletionKey. O>А поэтому вопрос остается, зачем тогда передавать адрес указателя на структуру WSAOVERLAPPED, чтобы в итоге получить ее адрес
Во первых: CompletionKey ассоциирован с файлом, а не с операцией. И если вы запускаете не более одной операции над файлом — это не значит что их нельзя запустить 1000500. Или запустить одновременно WSASend и WSARecv.
Во вторых: Даже если у вас per-file всегда работает лишь одна операция, то OVERLAPPED структуру можно завернуть в объект-состояние подключения, и получить его простым тайп-кастом, а не lookup-ом по мапе:
struct ConnectionState
{
WSAOVERLAPPED ovl;
int some;
int private;
int information;
};
struct ConnectionState *cs = malloc(sizeof(struct ConnectionState));
WSASend(...&cs->ovl);
...
и потом так ненавязчиво:
WSAOVERLAPPED *povl;
GetQueuedCompletionStatus(...&povl);
struct ConnectionState *cs = (struct ConnectionState *)povl;
Как много веселых ребят, и все делают велосипед...
Здравствуйте, ononim, Вы писали:
O>Во первых: CompletionKey ассоциирован с файлом, а не с операцией. И если вы запускаете не более одной операции над файлом — это не значит что их нельзя запустить 1000500. Или запустить одновременно WSASend и WSARecv.
Ну даже, если я запущу несколько операцией над сокетом/файлом, зачем мне WSAOVERLAPPED, если "внутреннее назначение полей WSAOVERLAPPED — недокументированные вещи напрямую их ковырять не стоит".
Если поля WSAOVERLAPPED напрямую ковырять не стоит — зачем тогда он нужен ?
O>>Во первых: CompletionKey ассоциирован с файлом, а не с операцией. И если вы запускаете не более одной операции над файлом — это не значит что их нельзя запустить 1000500. Или запустить одновременно WSASend и WSARecv. O>Ну даже, если я запущу несколько операцией над сокетом/файлом, зачем мне WSAOVERLAPPED, если "внутреннее назначение полей WSAOVERLAPPED — недокументированные вещи напрямую их ковырять не стоит". O>Если поля WSAOVERLAPPED напрямую ковырять не стоит — зачем тогда он нужен ?
Это — контескт асинхронной операцции, в его начале на самом деле лежит структура, в которую ядро асинхронно пишет результат — IO_STATUS_BLOCK — https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_io_status_block — и такую структуру требуют все IO сервисы ядра, типа https://docs.microsoft.com/en-us/windows/win32/devnotes/ntreadfile.
В случае синхронных апи, типа ReadFile/send() этот контекст можно положить на стек и забыть при завершении операции. Для асинхронных операций этот контекст должен ктото выделить на время работы операции. Этот ктото — это вы.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, ononim, Вы писали:
O>>Ну даже, если я запущу несколько операцией над сокетом/файлом, зачем мне WSAOVERLAPPED, если "внутреннее назначение полей WSAOVERLAPPED — недокументированные вещи напрямую их ковырять не стоит". O>>Если поля WSAOVERLAPPED напрямую ковырять не стоит — зачем тогда он нужен ? O>Это — контескт асинхронной операцции, в его начале на самом деле лежит структура, в которую ядро асинхронно пишет результат — IO_STATUS_BLOCK — https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_io_status_block — и такую структуру требуют все IO сервисы ядра, типа https://docs.microsoft.com/en-us/windows/win32/devnotes/ntreadfile. O>В случае синхронных апи, типа ReadFile/send() этот контекст можно положить на стек и забыть при завершении операции. Для асинхронных операций этот контекст должен ктото выделить на время работы операции. Этот ктото — это вы.
O>Для асинхронных операций этот контекст должен ктото выделить на время работы операции. Этот ктото — это вы.
Так я его и выделил и отправил в функцию WSASend при ее вызове.
Я ни как не могу понять, зачем мне GetQueuedCompletionStatus возвращает указатель на мою же структуру, что мне с ней делать ?
O>Так я его и выделил и отправил в функцию WSASend при ее вызове. O>Я ни как не могу понять, зачем мне GetQueuedCompletionStatus возвращает указатель на мою же структуру, что мне с ней делать ?
в одном потоке wsasend
в другом потоке GetQueuedCompletionStatus
в главном потоке может быть потребность в контекте из потока который отправил wsasend
и другими способами их получить нет
если вы не понимаете, значит оно вам не надо
самые лучшие знания, которые приходят из потребности а не из хотелки
Здравствуйте, reversecode, Вы писали:
R>в главном потоке может быть потребность в контекте из потока который отправил wsasend R>и другими способами их получить нет
А Вы можете привести пример этой потребности ?
R>если вы не понимаете, значит оно вам не надо R>самые лучшие знания, которые приходят из потребности а не из хотелки
Да это как бы не хотелка, все что мне надо это читать и писать в сокет или файл. И вот я не знаю, должен ли я как то использовать WSAOVERLAPPED.
Хотя предыдущий автор ononim, если я правильно его понял, сказал, что обращается к полям WSAOVERLAPPED — вообще не есть хорошо.
Здравствуйте, Optimus1, Вы писали:
O>Здравствуйте, reversecode, Вы писали:
R>>в главном потоке может быть потребность в контекте из потока который отправил wsasend R>>и другими способами их получить нет
O>А Вы можете привести пример этой потребности ?
смотрите в библиотеку asio
где оверлаппед это хендлер, который вызывается в главном потоке(ах)