Порты завершения и все что с ними связано
От: Optimus1  
Дата: 16.05.21 11:12
Оценка:
Здравствуйте,

Позвольте создать тему про порты завершения.

Собственно вот такой вопрос:

-Есть две функции: WSASend и GetQueuedCompletionStatus.
Обе функции одним из параметров принимают структуру WSAOVERLAPPED, в которую что то там записывают.

В случае с WSASend-GetQueuedCompletionStatus в WSAOVERLAPPED идет запись в параметр WSAOVERLAPPED.InternalHigh — то кол-во байт, которое якобы отправлено на данный момент.

1)И вот вопрос: Получается, что приходится для одной и той же операции создавать две структуру и два раза ее передавать, но, если WSASend используется совместно с портами завершения, то информацию пользователь же получает из очереди порта завершения посредством функции GetQueuedCompletionStatus куда и передает дублированную структуру WSAOVERLAPPED. Зачем же тогда две структуры передавать ?



2)И позвольте второй вопрос: у функции GetQueuedCompletionStatus — второй параметр это:

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


и соответственно, как уже писал выше 4ый параметр — это структура WSAOVERLAPPED, которая так в один из своих полей получает — "количество байтов, переданных в завершенной операции ввода-вывода.".
Зачем тогда нужен второй параметр ? Или зачем тогда передавать WSAOVERLAPPED, если есть второй параметр, куда GetQueuedCompletionStatus и так запишет нужное кол-во байт ?

Что то я запутался.
winsock winsock2 c++ completion port
Re: Порты завершения и все что с ними связано
От: reversecode google
Дата: 16.05.21 17:52
Оценка:
оверлапед нужно для много поточной архитектуры
считайте оверлапед как контекст
который передается в wsasend
а получает их GetQueuedCompletionStatus
Re[2]: Порты завершения и все что с ними связано
От: Optimus1  
Дата: 16.05.21 19:34
Оценка:
Здравствуйте, reversecode, Вы писали:

R>оверлапед нужно для много поточной архитектуры

R>считайте оверлапед как контекст
R>который передается в wsasend
R>а получает их GetQueuedCompletionStatus

Я это понимаю. Но, не понимаю зачем дублировать параметры, которые по сути возвращают одно и тоже значение.
Re[3]: Порты завершения и все что с ними связано
От: reversecode google
Дата: 16.05.21 20:09
Оценка:
O>Я это понимаю. Но, не понимаю зачем дублировать параметры, которые по сути возвращают одно и тоже значение.

я вас не понимаю, перефразируйте ваши мысли упрощенно

если вы о параметре который wsasend возращает количетство байт
так

https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasend
параметр ставится в нуль если используется оверлапед
или используется, если оверлапед не используется

lpNumberOfBytesSent

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.


или о чем речь ?
Re: Порты завершения и все что с ними связано
От: ononim  
Дата: 17.05.21 08:01
Оценка:
O>1)И вот вопрос: Получается, что приходится для одной и той же операции создавать две структуру и два раза ее передавать, но, если WSASend используется совместно с портами завершения, то информацию пользователь же получает из очереди порта завершения посредством функции GetQueuedCompletionStatus куда и передает дублированную структуру WSAOVERLAPPED. Зачем же тогда две структуры передавать ?
GetQueuedCompletionStatus _возвращает_ вам указатель на структуру LPOVERLAPPED, ранее переданную в WSASend. (ведь ее аргумент lpOverlapped — это двойной указатель).
На всякий случай отвечу на вопрос типа 'а зачем он мне его возвращает я ведь его сам знаю?' — затем что если вы запустили 100500 параллельных WSASend, по этому указателю вы сможете понять к какому именно из них относится этот результат.


O>В случае с WSASend-GetQueuedCompletionStatus в WSAOVERLAPPED идет запись в параметр WSAOVERLAPPED.InternalHigh — то кол-во байт, которое якобы отправлено на данный момент.

O>2)И позвольте второй вопрос: у функции GetQueuedCompletionStatus — второй параметр это:
O>

O>Указатель на переменную, которая получает количество байтов, переданных в завершенной операции ввода-вывода.

Потому что внутреннее назначение полей WSAOVERLAPPED — недокументированные вещи напрямую их ковырять не стоит. GetQueuedCompletionStatus просто выковыривает вам оттуда нужный вам параметр документированным способом.
Как много веселых ребят, и все делают велосипед...
Отредактировано 17.05.2021 8:02 ononim . Предыдущая версия .
Re[2]: Порты завершения и все что с ними связано
От: Videoman Россия https://hts.tv/
Дата: 18.05.21 10:29
Оценка:
Здравствуйте, ononim, Вы писали:

Согласен, но есть маленькое замечаение, вдруг кто не в курсе по поводу вот этого:

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.

Отредактировано 18.05.2021 10:32 Videoman . Предыдущая версия .
Re[2]: Порты завершения и все что с ними связано
От: Optimus1  
Дата: 20.05.21 08:14
Оценка:
Здравствуйте, ononim, Вы писали:


O>На всякий случай отвечу на вопрос типа 'а зачем он мне его возвращает я ведь его сам знаю?' — затем что если вы запустили 100500 параллельных WSASend, по этому указателю вы сможете понять к какому именно из них относится этот результат.


Вообще соответствие пакета, который мы достали из очереди с помощью GetQueuedCompletionStatus — и одного из 100500 параллельных WSASend — идентифицируется через CompletionKey.


O>Потому что внутреннее назначение полей WSAOVERLAPPED — недокументированные вещи напрямую их ковырять не стоит. GetQueuedCompletionStatus просто выковыривает вам оттуда нужный вам параметр документированным способом.


А поэтому вопрос остается, зачем тогда передавать адрес указателя на структуру WSAOVERLAPPED, чтобы в итоге получить ее адрес, если Вы сами говорите, что "внутреннее назначение полей WSAOVERLAPPED — недокументированные вещи напрямую их ковырять не стоит" и идентификация пакета и вызова WSASend определяется через CompletionKey, а кол-во отравленных или принятых байт определяется через второй параметр функции GetQueuedCompletionStatus.
То есть Вы противоречите сами себе получается ?
Отредактировано 20.05.2021 8:16 Optimus1 . Предыдущая версия .
Re[3]: Порты завершения и все что с ними связано
От: ononim  
Дата: 20.05.21 10:15
Оценка:
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;
Как много веселых ребят, и все делают велосипед...
Отредактировано 20.05.2021 10:35 ononim . Предыдущая версия . Еще …
Отредактировано 20.05.2021 10:21 ononim . Предыдущая версия .
Отредактировано 20.05.2021 10:16 ononim . Предыдущая версия .
Re[4]: Порты завершения и все что с ними связано
От: Optimus1  
Дата: 20.05.21 12:06
Оценка:
Здравствуйте, ononim, Вы писали:

O>Во первых: CompletionKey ассоциирован с файлом, а не с операцией. И если вы запускаете не более одной операции над файлом — это не значит что их нельзя запустить 1000500. Или запустить одновременно WSASend и WSARecv.


Ну даже, если я запущу несколько операцией над сокетом/файлом, зачем мне WSAOVERLAPPED, если "внутреннее назначение полей WSAOVERLAPPED — недокументированные вещи напрямую их ковырять не стоит".
Если поля WSAOVERLAPPED напрямую ковырять не стоит — зачем тогда он нужен ?
Re[5]: Порты завершения и все что с ними связано
От: ononim  
Дата: 20.05.21 12:18
Оценка:
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() этот контекст можно положить на стек и забыть при завершении операции. Для асинхронных операций этот контекст должен ктото выделить на время работы операции. Этот ктото — это вы.
Как много веселых ребят, и все делают велосипед...
Re[6]: Порты завершения и все что с ними связано
От: Optimus1  
Дата: 20.05.21 13:01
Оценка:
Здравствуйте, 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 возвращает указатель на мою же структуру, что мне с ней делать ?
Re[7]: Порты завершения и все что с ними связано
От: reversecode google
Дата: 20.05.21 13:21
Оценка:
O>Так я его и выделил и отправил в функцию WSASend при ее вызове.
O>Я ни как не могу понять, зачем мне GetQueuedCompletionStatus возвращает указатель на мою же структуру, что мне с ней делать ?

в одном потоке wsasend
в другом потоке GetQueuedCompletionStatus

в главном потоке может быть потребность в контекте из потока который отправил wsasend
и другими способами их получить нет

если вы не понимаете, значит оно вам не надо
самые лучшие знания, которые приходят из потребности а не из хотелки

ну или откройте код того же asio и изучите
Re[8]: Порты завершения и все что с ними связано
От: Optimus1  
Дата: 20.05.21 14:05
Оценка:
Здравствуйте, reversecode, Вы писали:

R>в главном потоке может быть потребность в контекте из потока который отправил wsasend

R>и другими способами их получить нет

А Вы можете привести пример этой потребности ?



R>если вы не понимаете, значит оно вам не надо

R>самые лучшие знания, которые приходят из потребности а не из хотелки

Да это как бы не хотелка, все что мне надо это читать и писать в сокет или файл. И вот я не знаю, должен ли я как то использовать WSAOVERLAPPED.
Хотя предыдущий автор ononim, если я правильно его понял, сказал, что обращается к полям WSAOVERLAPPED — вообще не есть хорошо.
Re[9]: Порты завершения и все что с ними связано
От: reversecode google
Дата: 20.05.21 14:15
Оценка:
Здравствуйте, Optimus1, Вы писали:

O>Здравствуйте, reversecode, Вы писали:


R>>в главном потоке может быть потребность в контекте из потока который отправил wsasend

R>>и другими способами их получить нет

O>А Вы можете привести пример этой потребности ?


смотрите в библиотеку asio
где оверлаппед это хендлер, который вызывается в главном потоке(ах)

https://github.com/chriskohlhoff/asio/blob/master/asio/include/asio/detail/impl/win_iocp_io_context.ipp#L160
https://github.com/chriskohlhoff/asio/blob/master/asio/include/asio/detail/impl/win_iocp_io_context.ipp#L472
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.