Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Особенности работы с IOCP, Особенности работы с IOCP 
:(
    Опции темы
NickAnd
Дата 27.3.2010, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 27.3.2010

Репутация: нет
Всего: нет



Пишу сервер с использованием IOCP.
1. Правильно ли для каждого вызова WSARecv, WSASend использовать свою структуру WSAOverlapped?
2. Как узнать, когда можно освободить память отведенную под WSAOverlapped?


PM MAIL   Вверх
Демо
Дата 27.3.2010, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 6
Всего: 50



Цитата(NickAnd @  27.3.2010,  16:23 Найти цитируемый пост)
1. Правильно ли для каждого вызова WSARecv, WSASend использовать свою структуру WSAOverlapped?


Не то чтобы неправильно, но не стоит каждый раз создавать.
Созданной один раз структуры хватит на всё время работы с созданным сокетом.


Цитата(NickAnd @  27.3.2010,  16:23 Найти цитируемый пост)
2. Как узнать, когда можно освободить память отведенную под WSAOverlapped?


Когда закончишь работать с перекрытым в/в с сокетом.

т.е. после CloseSocket можно освобождать память.


--------------------
    
PM MAIL ICQ Skype   Вверх
NickAnd
Дата 27.3.2010, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 27.3.2010

Репутация: нет
Всего: нет



У меня задача чуть сложнее:
Сервер принимает данные от клиента (WSARecv), передает на обработку и снова принимает (WSARecv). Для этой цепочки используется одна ("постоянная") WSAOverlapped.

В то же время асинхронно (по факту обработки) могут возникать данные для передачи обратно клиенту  (WSASend). Такие вызовы WSASend я делаю с отдельной ("временной") структурой WSAOverlpaped (отдельная под каждый вызов).

Соответственно как только получаю подтверждение завершения такой операции (GetQueuedCompletionStatus), то освобождаю память выделенную под "временную" WSAOverlapped (она мне больше не нужна).

Но, проблема в том, что FastMM4 иногда ругается: "изменились данные в ранее освобожденном блоке" и четко указывает мне на блок, который ранее выделялся для WSAOverlapped и конечно же был освобожден. Т.е. это  run-time ошибка FastMM4.

Есть подозрение, что Windows изменяет содержимое WSAOverlapped после успешного завершенния операции ввода-вывода.

Что посоветуете?



PM MAIL   Вверх
Демо
Дата 27.3.2010, 18:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 6
Всего: 50



Цитата(NickAnd @  27.3.2010,  17:08 Найти цитируемый пост)
Есть подозрение, что Windows изменяет содержимое WSAOverlapped после успешного завершенния операции ввода-вывода.


Я думаю, что можно быть полностью уверенным в этом, так как структура регистрируется при вызове WSARecv.

Возникает вопрос - зачем используется разные структуры для одного и того же сокета.
В любом случае передача данных выполняется последовательно.

Результат использования логичен - AV.

Добавлено через 1 минуту и 4 секунды
Цитата(NickAnd @  27.3.2010,  17:08 Найти цитируемый пост)
Что посоветуете?


Трудно посоветовать не зная логики работы приложения.
Но избавляться от 2-х разных структур нужно, как мне представляется.

Добавлено через 3 минуты и 54 секунды
Хотя насчёт одной структуры могу быть неправ.

Добавлено через 4 минуты и 35 секунд
Есть возможность код выложить?

Добавлено через 11 минут и 7 секунд
А Event в каждой структуре создаёшь?


--------------------
    
PM MAIL ICQ Skype   Вверх
NickAnd
Дата 27.3.2010, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 27.3.2010

Репутация: нет
Всего: нет



Цитата(Демо @ 27.3.2010,  18:11)
Возникает вопрос - зачем используется разные структуры для одного и того же сокета.

Логично. Но мне не совсем понятна роль структуры.
В связи с этим вопрос: нужно ли ее обнулять перед каждым вызовом WSARecv, WSASend

Добавлено через 8 минут и 18 секунд
Цитата(Демо @ 27.3.2010,  18:11)
В любом случае передача данных выполняется последовательно.

Не очень согласен.
Возможна ситуация, когда сервер ждет от клиента данные (завершения очередного WSARecv) а в это время уже отправил несколько раз данные (WSASend) для клиента.

И еще, после закрытия сокета со стороны клиента не могу нормально освободить память даже для "одной на сокет" WSAOverlapped-структуры.
Причина -- все та же: изменение данных структуры системой после завершения операции ввода-вывода.

Может есть все-таки "грамотный" способ определения того момента, когда она уже не используется и может быть освобождена?
PM MAIL   Вверх
Демо
Дата 27.3.2010, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 6
Всего: 50



Вот из MSD полезный материал - http://msdn.microsoft.com/en-us/library/ms686358(VS.85).aspx
Вроде как Event в твоём случае обязательно должен использоваться для каждой структуры.

Цитата(NickAnd @  27.3.2010,  18:48 Найти цитируемый пост)
В связи с этим вопрос: нужно ли ее обнулять перед каждым вызовом WSARecv, WSASend


Да, перед каждой операцией.

Добавлено через 12 минут и 20 секунд
Ещё вопрос:

Есть такой параметр dwCompKey.

Правильно ли он используется?


--------------------
    
PM MAIL ICQ Skype   Вверх
NickAnd
Дата 27.3.2010, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 27.3.2010

Репутация: нет
Всего: нет



Спасибо за ссылку!

В моем случае наверно нужно попробовать WSAGetOverlappedResult.

Добавлено через 4 минуты и 48 секунд
Цитата(Демо @ 27.3.2010,  19:15)
Ещё вопрос:

Есть такой параметр dwCompKey.

Правильно ли он используется?

Не очень понял вопрос... 

Поэтому отвечу вопросом на вопрос: Как правильно его использовать?

Я в этом параметре храню данные (структуру), которые связаны с открытым сокетом (сокет, дата-время открытия, дата-время последней операции, данные полученные последней операцией WSARecv  и т.п.)
PM MAIL   Вверх
Демо
Дата 27.3.2010, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 6
Всего: 50



Цитата(NickAnd @  27.3.2010,  19:39 Найти цитируемый пост)
Не очень понял вопрос... 


Я имел ввиду следущее:
Поток, который получает управление, ничего не знает о том, зачем и кто его пробудил от спячки.
После выполнения GetQueuedCompletionStatus в этом потоке получаем WSAOverlapped-структуру и dwCompKey, связанные с запросом, реакция на который произошла.

В этот момент у тебя никаких коллизий не возникает, путаницы с объектами?


Цитата(NickAnd @  27.3.2010,  19:39 Найти цитируемый пост)
Я в этом параметре храню данные (структуру), которые связаны с открытым сокетом (сокет, дата-время открытия, дата-время последней операции, данные полученные последней операцией WSARecv  и т.п.)


Ну в принципе так и есть.

Я обычно создаю класс, в котором и хранится вся связанная с сеансом информация, методы обработки, связанные с объетом.
Ссылку на экземпляр класса и передаю.

Кстати, обнулять каждый раз структуру не нужно, если тебе нужны данные, которые она содержит.
Нужно только правильно обрабатывать и устанавливать поле hEvent.


--------------------
    
PM MAIL ICQ Skype   Вверх
NickAnd
Дата 27.3.2010, 22:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 27.3.2010

Репутация: нет
Всего: нет



Цитата(Демо @ 27.3.2010,  20:22)
В этот момент у тебя никаких коллизий не возникает, путаницы с объектами?


Нет, путаницы не возникает. Все данные которые нужны для идентификации "кто это" у меня хранятся в структуре (классе) на который указывает dwCompKey

Добавлено через 14 минут и 19 секунд
Цитата(Демо @ 27.3.2010,  20:22)
Кстати, обнулять каждый раз структуру не нужно, если тебе нужны данные, которые она содержит.
Нужно только правильно обрабатывать и устанавливать поле hEvent.

Если возможно по поводу hEvent поподробней.

На сейчас отработанные "временные" WSAOverlapped-структуры складываю в отдельный список (предварительно освобождая буфер WSABUF -- он у меня прицепом к структуре идет), чтобы потом освободить занятую под ними память (возможно отдельным thread-ом "чистильщиком").

Но в какой момент освобождать собственно TWSAOverlapped пока не понимаю.

Дело в том, что даже освобождение "основных" WSAOverlapped-структур при закрытии сокета клиентом (GetQueuedCompletionStatus = false или lpNumberOfBytesTransferred = 0) приводит к ситуации, когда имеем изменения в освобожденном блоке.

Мне кажется, что должен быть механизм, который однозначно гарантирует, что "заявленная" WSAOverlapped-структура в одном из вызовов WSARecv, WSASSend системой больше изменяться не будет...

Гуглю... пока безрезультатно... 
Нашел только на MSDN:

The closesocket function closes a socket. Use it to release the socket descriptor s so that further references to s  fail with the error WSAENOTSOCK. If this is the last reference to an underlying socket, the associated naming information and queued data are discarded. Any pending blocking, asynchronous calls issued by any thread in this process are canceled without posting any notification messages.

Any pending overlapped send and receive operations ( WSASend/ WSASendTo/ WSARecv/ WSARecvFrom with an overlapped socket) issued by any thread in this process are also canceled. Any event, completion routine, or completion port action specified for these overlapped operations is performed. The pending overlapped operations fail with the error status WSA_OPERATION_ABORTED.

An application should not assume that any outstanding I/O operations on a socket will all be guaranteed to completed when closesocket returns. The closesocket function will initiate cancellation on the outstanding I/O operations, but that does not mean that an application will receive I/O completion for these I/O operations by the time the closesocket function returns. Thus, an application should not cleanup any resources (WSAOVERLAPPED structures, for example) referenced by the outstanding I/O requests until the I/O requests are indeed completed. 


А как узнать когда ж они "are indeed completed" ?
PM MAIL   Вверх
Демо
Дата 28.3.2010, 01:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 6
Всего: 50



Цитата(NickAnd @  27.3.2010,  22:39 Найти цитируемый пост)
А как узнать когда ж они "are indeed completed" ?


Выполни предварительно shutdown...


--------------------
    
PM MAIL ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0818 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.