|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
Есть функция (для простоты восприятия сокращена обработка ошибок и чистка памяти), которая вычитывает данные из named pipe канала. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36.
Не понимаю, почему ReadFile считает что вычитала все данные, если я увеличиваю размер буфера dwBufferSize в два раза после каждой неудачной итерации (см. закоментированную строку в коде - удвоенный размер)? Например, если поступили 200 КБ данных, то ReadFile сначала вычитывает 64КБ и возвращает FALSE, потом я предоставляю ей удвоенный буфер в 128КБ. ReadFile вычитывает, скажем, еще 70КБ. ReadFile при этом возвращает TRUE, в dwReadBytes помещает размер считанных данных меньший, чем переданный ей буфер dwBufferSize. Если сложить все что я вычитал (64 + 70 < 200), то получится что dwTotalSize меньше, чем реально было данных, которые были помещенны в канал отправителем. Существует два финта ушами, которые решают проблему: 1. перед началом чтения вызвать функцию PeekNamedPipe , узнать сколько данных, выделить нужный буфер сразу и считать все 2. закоментировать строку с удвоением буфера и читать данные только в буфер одинакового размера - 64КБ Я бы всегда пользовался первым методом, т.к. не пришлось бы геморройничать с перевыделением буфера, копированием данных и прочим, но я пока не обкатал его и доверия он особо у меня не вызывает. Второй метод меня не устраивает, т.к. при значительных объемах передаваемых данных (700 МБ и более), вычитывать их по 64КБ получается оччееееень дооооооолго. Поэтому я и решил на каждую неудачную итерацию удваивать размер буфера, но столкнулся с тем, что система считает, что я все вычитал, хотя реально данных пришло больше, что и подтверждает PeekNamedPipe , если ее вызвать в самом начале. Либо я чего-то не понимаю, либо к концу рабочего дня уже начинаю тупить и не вижу ошибку в своем коде. Есть идеи, что это может быть ? PS именнованный канал создан с IO буфером в 64 КБ сервер, перед закрытием канала вызывает FlushFileBuffers клиент вычитывает данные после вызова TransactNamedPipe с переданными пустыми значениями параметров (для ускорения сетевого обмена, вместо WriteFile/ReadFile). То есть функция ничего не вычитывает сама, только выполняет отправку данных (запрос) и организует прием (ответ) без считывания данных, дальше работает моя RecvData. Я знаю что в MSDN сказано что TransactNamedPipe не гарантирует доставку данных свыше 64КБ, тогда почему стабильно работают два других метода ? -------------------------------------------------------------- o(O_O)o ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2018, 17:05 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
Второй метод - единственно работающий. И не беспокойся, дольше он не будет. Не надо использовать MESSAGE режим. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2018, 17:14 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
Cerebrum, почему по вашему она не может заполнить то что ей предоставили? наверное надо проверять сколько прочиталось pNumberOfBytesRead... автор2. закоментировать строку с удвоением буфера и читать данные только в буфер одинакового размера - 64КБ OVERLAPPED и два буфера - пока один обрабатывается, в другой читается. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2018, 17:20 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
Dimitry SibiryakovВторой метод - единственно работающий. И не беспокойся, дольше он не будет. Не надо использовать MESSAGE режим. Да я использую MESSAGE режим, т.к. он мне удобнее и лучше отражает логику работы службы. Я бы не парился, если бы его (стабильный буфер) не попробовал, когда вычитываю данные, то он тупит очень :) Речь не о миллисекундах, там уже на минуты счет идет в сети на 1Gbps сетевухах, даже если все в виртуалках на одном компе-гипервизоре. Я пробовал пересылать около гигабайта данных в режиме с удваением буфера (оказалось что не все данные приходили :) ), но даже если я не досчитался нескольких десятков/сотен килобайт, такой подход работает быстрее.... Наверное придется тогда мучить первый способ, обложить его проверками и тестами ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2018, 17:22 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
kealon(Ruslan)почему по вашему она не может заполнить то что ей предоставили? понятия не имею, сеть стабильная 1Gbps :), комп уровня Core i7 6700K c 32 GB RAM на борту kealon(Ruslan)наверное надо проверять сколько прочиталось pNumberOfBytesRead... именно так я и нашел этот косяк. отправленный пакет находится в сжатом виде, когда его считал, то расжать не смог из-за ошибки расжимальщика, начал выяснять и обнаружил что получаю не все данные ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2018, 17:26 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
kealon(Ruslan)OVERLAPPED и два буфера - пока один обрабатывается, в другой читается. я не думаю, что здесь проблема производительности, т.к. в тестовой среде у меня пока один клиент - один сервер - один запрос, плюс PeekNamedPipe говорит видит все пришедшие данные в полном объеме - это 100% проверено и перепроверено ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2018, 17:29 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
Cerebrum, покажи, как канал создаешь. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2018, 17:40 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
Котовасияпокажи, как канал создаешь. если сильно упростить, то клиент коннектится примерно так (или вы про серверную часть ?) Код: plaintext 1. 2. 3. 4. 5. 6. 7.
PS. финт номер 1 рассыпался на тесте, тоже вычеркиваем ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2018, 17:56 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
Cerebrumотправленный пакет находится в сжатом виде, когда его считал, то расжать не смог из-за ошибки расжимальщика, начал выяснять и обнаружил что получаю не все данные Именно поэтому не надо использовать MESSAGE. Этот режим изначально сделан для сообщений размером в считанные байты. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2018, 18:03 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
Dimitry SibiryakovCerebrumотправленный пакет находится в сжатом виде, когда его считал, то расжать не смог из-за ошибки расжимальщика, начал выяснять и обнаружил что получаю не все данные Именно поэтому не надо использовать MESSAGE. Этот режим изначально сделан для сообщений размером в считанные байты. склонен прислушаться к вашему мнению, буду пробовать ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2018, 18:06 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
Cerebrumбуду пробовать В ходе этого процесса попробуй поразмыслить на фактом, что именованные трубки являются одним из основных транспортов MS SQL. И лично я не слышал жалоб, чтобы до сервера не всё доходило. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2018, 18:15 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
Cerebrum, а при создании канала /*см. CreateNamedPipe()*/- указал режим PIPE_TYPE_MESSAGE? ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2018, 18:46 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
КотовасияCerebrum, а при создании канала /*см. CreateNamedPipe()*/- указал режим PIPE_TYPE_MESSAGE? Код: plaintext 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2018, 19:57 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
malloc() разве не пережиток C ? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.09.2018, 00:53 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
полудухmalloc() разве не пережиток C ?malloc() это функция менеджера памяти использующегося в С. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.09.2018, 01:57 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
White Owlполудухmalloc() разве не пережиток C ?malloc() это функция менеджера памяти использующегося в С. ну. в C++ то она зачем, там есть new & co? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.09.2018, 06:06 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
полудухв C++ то она зачем, там есть new & co? Когда new сумеет выделять что-то сложнее массива одинаковых структур, тогда о нём можно будет говорить серьёзно. До тех пор std::malloc() - наше всё. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
12.09.2018, 12:26 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
полудухWhite Owlпропущено... malloc() это функция менеджера памяти использующегося в С. ну. в C++ то она зачем, там есть new & co?ахах, а ты думаешь new святым духом пользуется для выделения памяти =) ... |
|||
:
Нравится:
Не нравится:
|
|||
12.09.2018, 19:20 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
Siemarglполудухпропущено... ну. в C++ то она зачем, там есть new & co?ахах, а ты думаешь new святым духом пользуется для выделения памяти =) Код: plaintext 1. 2. 3. 4.
на какой-то конфе кто-то ляпнул, что в C++ есть new и теперь можно malloc() не трогать сам то я джун ещё в сях, вникаю ... |
|||
:
Нравится:
Не нравится:
|
|||
12.09.2018, 22:14 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
а, этот "кто-то" это Страуструп... ляпнул . авторОтказаться от использования malloc() в пользу оператора new, от realloc() — в пользу типа vector. Более безопасным будет использование умных указателей, таких как shared_ptr и unique_ptr, доступных с одиннадцатой версии стандарта. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.09.2018, 05:28 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
полудух, ляпнул то он ляпнул, вот только чуть что серьёзное и все эти мальчики-побегайчики разбегаются и приходит жёсткий си хотя если воспринимать этот как совет для ограниченных, то да, дельный ... |
|||
:
Нравится:
Не нравится:
|
|||
14.09.2018, 10:56 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
Все он правильно сказал. Надо пользоваться более высокоуровневым new. А то что внутре у ней malloc, это можно и не знать ... |
|||
:
Нравится:
Не нравится:
|
|||
14.09.2018, 20:50 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
malloc() + memset() или malloc() + WTF! ... |
|||
:
Нравится:
Не нравится:
|
|||
14.09.2018, 21:03 |
|
Чтение из именнованного канала
|
|||
---|---|---|---|
#18+
Переписал все с MESSAGE_TYPE на BYTE_TYPE. Теперь сервер создается как PIPE_TYPE_BYTE|PIPE_READMODE_BYTE|PIPE_WAIT|PIPE_ACCEPT_REMOTE_CLIENTS, а толку - ни фига! Как клиент недогружал так и недогружает данные, пока принудительно не скажешь, что буфер не более 64К. На серверной стороне WriteFile сообщает, что все отправлено столько сколько просили. Кроме того, пробовал у WriteFile бить поток на блоки по 64К - не помогло. Сервер и в этом случае отрабатывает ок. Клиент же (ReadFile) глотает начало блока с заголовком, потом еще 64КБ, потом как получится и сообщает: 0x000000E9 - No process is on the other end of the pipe... хотя процесс висит и пашет. SetNamedPipeHandleState говорит, что клиент работает в режиме PIPE_TYPE_BYTE и ошибки здесь в выборе режима нет. Думал может где все-таки косяк и я не вижу и где-то все же закрываю серверный канал раньше времени (вроде как FlushFileBuffers не должна этого позволять). Специально закоментил код, который вызывает DisconnectNamedPipe и CloseHandle, оставил только FlushFileBuffers - клиент тупо завис на ReadFile и больше ничего не вычитывает. Короче, в жопу! Будет работать с 64К - пусть работает с 64К! Всем отметившимся - спасибо ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2018, 17:40 |
|
|
start [/forum/topic.php?fid=57&fpage=16&tid=2017751]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
27ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
65ms |
get tp. blocked users: |
2ms |
others: | 39ms |
total: | 180ms |
0 / 0 |