Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> WSAEventSelect Model and event Notification, не получается поймать рисив с сервера 
:(
    Опции темы
knut
Дата 11.11.2007, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



вот обрезанный пример где точно есть наличие проблемы.
ормально кмпилитсяsmile
p.s
буду признателен за помпшь

Присоединённый файл ( Кол-во скачиваний: 11 )
Присоединённый файл  EventSelectIOModel.rar 19,15 Kb


--------------------
Цитата

Многие вещи нам непонятны не оттого, что наши понятия слабы, а оттого, что данные вещи не входят в круг наших понятий.
PM MAIL   Вверх
xvr
Дата 12.11.2007, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(knut @ 11.11.2007,  13:44)
вот обрезанный пример где точно есть наличие проблемы.
ормально кмпилитсяsmile
p.s
буду признателен за помпшь

Да уж, наличие проблемы есть smile

Код

bool CSocketThread::StartThread(CSocket *pSocket)
{
    m_pSocket = pSocket;
    m_Event[m_EventTotal] = WSACreateEvent();
    ++m_EventTotal;
    
    //recvOv.hEvent = m_Event[m_EventTotal];

    WSAEventSelect(m_pSocket->m_hsocket, m_Event,FD_READ|FD_WRITE);
    m_ThreadHandle = CreateThread(NULL, 0, &ThreadProc, (LPVOID)this, 0, &m_threadID);
...
В WSAEventSelect рекомендуется передавать ОДИН event, а не весь массив целиком smile 2й параметр должен быть m_Event[m_EventTotal-1]

Далее, передача данных:
Код

typedef struct  tagPACKET
{
    friend class CSocket; 
    char        *pBuffer;
    DWORD        buffer1_len;
    WSAOVERLAPPED  overlapped;
    
    
    tagPACKET();
    ~tagPACKET(){}

}PACKET;

tagPACKET::tagPACKET()
{
    
    char *pBuffer = "dlfjk;sldkjf;lksd;fk";
    
}
В дальнейшем данные передаются из PACKET::pBuffer, который не инициализированн, т.к. в конструкторе инициализируется ЛОКАЛЬНАЯ ПЕРЕМЕННАЯ pBuffer, а не поле структуры.

Про == вместо != я уже писал:
Код

if(SOCKET_ERROR == WSAEnumNetworkEvents(this_.m_Socket[dw_Index - WSA_WAIT_EVENT_0],
    this_.m_Event[dw_Index - WSA_WAIT_EVENT_0],&NetworkEvents))


PM MAIL   Вверх
knut
Дата 12.11.2007, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



xvr
спасибо тебе за замечание
но вот исправленный вариант.
но меня убивает то что я не могу понять почему у меня WSAEventSelect е зависает  и  не как не выxодет. smile 
я WSARecive(...)  вызвал в main() е у меня рисив нормально прошел.
а вот посадить его на ивент не как не получается. не пойму то я не так делаю в организации потоковай модели.?


Присоединённый файл ( Кол-во скачиваний: 14 )
Присоединённый файл  EventSelectIOModel.rar 19,69 Kb


--------------------
Цитата

Многие вещи нам непонятны не оттого, что наши понятия слабы, а оттого, что данные вещи не входят в круг наших понятий.
PM MAIL   Вверх
xvr
Дата 12.11.2007, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(knut @ 12.11.2007,  22:24)
xvr
спасибо тебе за замечание
но вот исправленный вариант.
но меня убивает то что я не могу понять почему у меня WSAEventSelect е зависает  и  не как не выxодет. smile 
я WSARecive(...)  вызвал в main() е у меня рисив нормально прошел.
а вот посадить его на ивент не как не получается. не пойму то я не так делаю в организации потоковай модели.?

Убери строку
Код

 WSAResetEvent(this_.m_Event[dw_Index - WSA_WAIT_EVENT_0]);

в конце цикла обработки event'ов в CSocketThread::ThreadProc. Этот event автоматически сбрасывается в WSAWaitForMultipleEvents и снова устанавливается в теле обработки, после чего ты его сбрасываешь вручную и в таком состоянии он остается навсегда :(
Кстати, отправка данных по FD_WRITE тоже не будет работать - вот выдержка из описания WSAEventSelect 
Цитата

An FD_WRITE network event is recorded when a socket is first connected with connect/WSAConnect or accepted with accept/WSAAccept, and then after a send fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, an application can assume that sends are possible starting from the first FD_WRITE network event setting and lasting until a send returns WSAEWOULDBLOCK. After such a failure the application will find out that sends are again possible when an FD_WRITE network event is recorded and the associated event object is set.

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


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

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



knut
Эээ... как это так?! 
Код
paket.overlapped.hEvent = HANDLE(FD_WRITE);
Как это ты так хитрым мановением руки превращаешь константу в хендл евента? а ведь этот хэндл передается на вход WSASend!
Далее, почему-то везде используются расширения WSA... а тут:
Код

if(SOCKET_ERROR != connect(m_hsocket,(sockaddr *)&dest_addr,sizeof(dest_addr)))
почему-то просто connect. Может надо WSAConnect? Если уж используешь расширения WSA - так используй везде (оно не обязательно, но все-таки). Кстати, МСДН глаголет, что
Цитата
With a nonblocking socket, the connection attempt cannot be completed immediately. In this case, connect will return SOCKET_ERROR, and WSAGetLastError will return WSAEWOULDBLOCK. In this case, there are three possible scenarios:
...
    * If the application is using WSAEventSelect to indicate interest in connection events, then the associated event object will be signaled indicating that the connect operation is complete (successfully or not).
поэтому connect (равно как и WSAConnect) должен вернуть SOCKET_ERROR (насколько я понял, идея - в использовании неблокирующих сокетов), поэтому приведенное сравнение нелогично...
Так же не совсем понятна идея использования массива евентов при вызове WSAEventSelect. В МСДН сказано:
Цитата
It is not possible to specify different event objects for different network events. The following code will not work; the second call will cancel the effects of the first, and only the FD_WRITE network event will be associated with hEventObject2:
Код

rc = WSAEventSelect(s, hEventObject1, FD_READ);
rc = WSAEventSelect(s, hEventObject2, FD_WRITE); //bad
А следовательно - неоправдано применение и WSAWaitForMultipleEvents. Если бы ты писал сервер-клиента, тогда еще можно понять: один евент на сервер, один - на клиент, но у тебя только клиентская сторона, поэтому достаточно одного событийного объекта...
А зачем ты из процедуры потока ThreadProc напрямую обращаешься к объектам CSocket obsocket и tagPACKET opacket без синхронизации? В таком случае - ты никак не защищен от межпотоковых коллизий и порчи данных... Про утечки памяти при таком использовании потока я уж и не говорю (нет выхода из цикла потоковой функции)...
Ну и самое интересное: при запуске потока ты инициализируешь на обработку евентов сокет m_hsocket объекта CSocket
Код
int res = WSAEventSelect(m_pSocket->m_hsocket, m_Event[m_EventTotal-1],FD_READ|FD_WRITE);
m_ThreadHandle = CreateThread(NULL, 0, &ThreadProc, (LPVOID)this, 0, &m_threadID);
...
а уже в потоке тестируешь на евенты массив неинициализированных и неиспользуемых сокетов this_.m_Socket класса CSocketThread:
Код
if(SOCKET_ERROR != WSAEnumNetworkEvents(this_.m_Socket[dw_Index - WSA_WAIT_EVENT_0],
this_.m_Event[dw_Index - WSA_WAIT_EVENT_0],&NetworkEvents))
несколько странно имхо...
Ну и по мелочи - куча недочетов типа: Функция CSocket::OpenSoket возвращает тип bool, а ты пишешь return m_hsocket типа SOCKET
Вообще, складывается такое ощущение, что ты просто натаскал из разных источников куски кода и пытался придать им работающий вид... 
Цитата
я не могу понять почему у меня WSAEventSelect е зависает  и  не как не выxодет
Кстати, у меня на этом месте не зависает почему-то...


--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

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


 




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


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

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