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

Поиск:

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


Опытный
**


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

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



день добрый.
Делаю клиентский ТCP-шний сокет используя меxанизм евентов а точнее WSAEventSelect.
есть 2 класса
1. сам класс CSocket 
Код

class CSocket
{
public:
        CSocket();
        virtual ~CSocket();
public:
    bool Connect(const char *DestAddress,int aDestPort);
    void Close();
    bool OpenSoket(int aSocketType, int aPort, const char * aLocalAddress);

    int OnSend(PACKET &paket);
    int OnRecive();
    int GetSendResult(bool bWait);
public:
    SOCKET m_hsocket;
    DWORD dwError;
    bool bltConn;
};

и соответственно реализация всеx метов.
Код

bool CSocket::OpenSoket(int aSocketType, int aPort, const char * aLocalAddress)
{
    m_hsocket = socket(AF_INET,aSocketType,IPPROTO_TCP );
    if(m_hsocket == INVALID_SOCKET)
    {
        dwError = ::WSAGetLastError();
        return false;
    }
    else
        return m_hsocket;
}

bool CSocket::Connect(const char *DestAddress,int aDestPort)
{
    
    sockaddr_in dest_addr;
    HOSTENT *hst;
    
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port   = htons(PORT);
    if (inet_addr(SERVERADDR)!=INADDR_NONE)
         dest_addr.sin_addr.s_addr=inet_addr(SERVERADDR);
     else
           if (hst=gethostbyname(SERVERADDR))
           ((unsigned long *)&dest_addr.sin_addr)[0]=((unsigned long **)hst->h_addr_list)[0][0];
    else
    {
        printf("Invalid address %s\n",SERVERADDR);
        closesocket(m_hsocket);
    }
           if(SOCKET_ERROR != connect(m_hsocket,(sockaddr *)&dest_addr,sizeof(dest_addr)))
                bltConn = true;
           else
               printf("Connect error %d\n",WSAGetLastError());
    
    return bltConn;


}

int CSocket::OnRecive()
{

    WSABUF recv_buf;
    DWORD NumberOfDataREcived = 0;
    LPOVERLAPPED lpOverlapped;
    DWORD dwFlag = 0;


    recv_buf.buf = 0;
    recv_buf.len = 0;


    int LastError = 0;
    if(INVALID_SOCKET == WSARecv(m_hsocket,&recv_buf,1,&NumberOfDataREcived,&dwFlag,lpOverlapped,NULL))
    {
        LastError = ::WSAGetLastError();
        return LastError;
    }
    return 0;

    
}

int CSocket::OnSend(PACKET &paket)
{
    WSABUF buffer;
    int nLastError;
    buffer.buf = paket.pBuffer;
    buffer.len = strlen(paket.pBuffer);
    DWORD dwNumberOfBytesSent = 0;
    
    LPWSAOVERLAPPED lpOverlapped = &paket.overlapped;
    if(WSASend(m_hsocket,&buffer,1,&dwNumberOfBytesSent,0,lpOverlapped,NULL))
    {
        nLastError = WSAGetLastError();
            return nLastError;
    }


    return 0;
}

int CSocket::GetSendResult(bool bWait)
{
    WSAOVERLAPPED poverlapped;
    DWORD pTransfer = 0;
    DWORD dwFlag = 0;
    DWORD deError;
        if(!WSAGetOverlappedResult(m_hsocket,&poverlapped,&pTransfer,bWait,&dwFlag))    
        deError = WSAGetLastError();
    return dwError;
}

и класс thread и сажаю все евенты.
Код

class CSocketThread
{
public:
    CSocketThread();
    virtual ~CSocketThread();
public:
    bool  StartThread(CSocket * pSocket,HANDLE hEvent);
    static void  _cdecl ThreadProc(LPVOID pVoid);
    bool RegisterEvent(SOCKET s, DWORD dwEvent);

public:
    DWORD       m_threadID;
    HANDLE      m_ThreadHandle;
    CSocket           *m_pSocket;

    int     m_nLastError;
    DWORD       m_EventTotal;

    SOCKET      m_Socket[WSA_MAXIMUM_WAIT_EVENTS];
    SOCKET      m_dwEvents[WSA_MAXIMUM_WAIT_EVENTS];
    WSAEVENT             m_Event[WSA_MAXIMUM_WAIT_EVENTS];

};

с медодами старт и воркертред.
Код

bool CSocketThread::StartThread(CSocket *pSocket,HANDLE hEvent)
{

    m_pSocket = pSocket;
    WSAEventSelect(m_pSocket->m_hsocket, &hEvent,FD_READ|FD_WRITE);
    m_ThreadHandle = (HANDLE)_beginthread(&ThreadProc,0,NULL);
    if(!m_ThreadHandle)
    {
        m_pSocket == NULL;
        return false;
    }
    else
            return m_threadID;


    return false;
}

и сам воркер
Код

void CSocketThread::ThreadProc(LPVOID pVoid,)
{
    CSocketThread  &this_ =  *(CSocketThread*)pVoid;
    WSANETWORKEVENTS NetworkEvents;
    while(1)
    {
        
        DWORD dw_Index = WSAWaitForMultipleEvents(1,this_.m_Event,FALSE,WSA_INFINITE,FALSE);
        if(dw_Index == SOCKET_ERROR)
        {
            this_.m_nLastError = WSAGetLastError();
        }

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

            if(NetworkEvents.lNetworkEvents & FD_CONNECT)
            {
                obsocket.Connect(SERVERADDR,PORT);
            }
            if(NetworkEvents.lNetworkEvents & FD_READ)
            {
                obsocket.OnRecive();
            }
            if(NetworkEvents.lNetworkEvents & FD_WRITE)
            {
                obsocket.OnSend(opacket);
            }
        }

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


}

так вот кажвый евент сажаю в поток.
это все что я делаю.
Код

socket_object.OpenSoket(SOCK_STREAM ,9998,"192.168.0.136");
socket_object.Connect("192.168.0.136",9998);
HANDLE hEvent = WSACreateEvent();
_thread.StartThread(&socket_object,hEvent);

так вот сейчас проблема.
создаю сокет,конектаюс к серверу.и посылаю сообшения и жду рисива но не какого ресива не приxодит.
не как не пойму в чем проблема та? 


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

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


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


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

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



выложи хоть минимально обрезанный компилируемый исходник, а то я забодался обтачивать напильником твои огрызки для получения воспроизводимости проблемы... В частности, непонятно что за переменные obsocket и  opacket... Ну и по мелочи, в итоге набегает пара десятков ошибок... Так же не видно функции WSAStartup()...


--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
knut
Дата 9.11.2007, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



ama_kid
obsocket и  opacket это обекты классов CSocket и структуры Paket.
Так же не видно функции WSAStartup()..
есть она точно и не в ней проблемма .

так вот зделав классы сокет и тред.начинаем релизац.клиентакого сокета.
1.создаем сокет.
2.конектимся к серверу и ждем рисива но не какого рисива не получаем.
 вот 2 метода релиз. евентную модель.
Код

bool CSocketThread::StartThread(CSocket *pSocket)
{

    m_pSocket = pSocket;
    m_Event[m_EventTotal] = WSACreateEvent();
    ++m_EventTotal;

    
    WSAEventSelect(m_pSocket->m_hsocket, &m_Event,FD_READ|FD_WRITE);
        m_ThreadHandle = (HANDLE)_beginthread(&ThreadProc,0,NULL);
    if(!m_ThreadHandle)
    {
        m_pSocket == NULL;
        return false;
    }
    else
        return m_threadID;


    
}

 и воркер евентов.
Код

void CSocketThread::ThreadProc(LPVOID pVoid)
{
    CSocketThread  &this_ =  *(CSocketThread*)pVoid;
    WSANETWORKEVENTS NetworkEvents;
    while(1)
    {
        
        DWORD dw_Index =    WSAWaitForMultipleEvents(m_EventTotal,this_.m_Event,FALSE,WSA_INFINITE,FALSE);
        if(dw_Index == SOCKET_ERROR)
        {
            this_.m_nLastError = WSAGetLastError();
        }

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

            if(NetworkEvents.lNetworkEvents & FD_CONNECT)
            {
                obsocket.Connect(SERVERADDR,PORT);
            }
            if(NetworkEvents.lNetworkEvents & FD_READ)
            {
                obsocket.OnRecive();
            }
            if(NetworkEvents.lNetworkEvents & FD_WRITE)
            {
                obsocket.OnSend(opacket);
            }
        
        }

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


}



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

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


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

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



Цитата(knut @  9.11.2007,  11:21 Найти цитируемый пост)
m_Event[m_EventTotal] = WSACreateEvent();
о. уже переделал... smile а раньше вообще на неинициализированном m_Event wait делал или таки где-то его инитил? не видно ж...
Цитата(ama_kid @  9.11.2007,  10:41 Найти цитируемый пост)
выложи хоть минимально обрезанный компилируемый исходник
+1
PM MAIL   Вверх
xvr
Дата 9.11.2007, 14:57 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Код

 if(SOCKET_ERROR == WSAEnumNetworkEvents(this_.m_Socket[dw_Index - WSA_WAIT_EVENT_0],
            this_.m_Event[dw_Index - WSA_WAIT_EVENT_0],&NetworkEvents))
Может все же SOCKET_ERROR != WSAEnumNetworkEvents ?
PM MAIL   Вверх
knut
Дата 9.11.2007, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



xvr
да этого ифа не доходит 
Код

WSAWaitForMultipleEvents(...)  

ждет ждет но не чего не получает


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

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


Эксперт
****


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

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



Цитата(knut @ 9.11.2007,  15:33)
xvr
да этого ифа не доходит 
Код

WSAWaitForMultipleEvents(...)  

ждет ждет но не чего не получает

Глупый вопрос - а сервер точно что-то отправляет? Может и получать нечего? 
PM MAIL   Вверх
knut
Дата 9.11.2007, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



xvr
Цитата

Глупый вопрос - а сервер точно что-то отправляет? Может и получать нечего?  

да отправляет 


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

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


Эксперт
****


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

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



Цитата(knut @ 9.11.2007,  17:07)
xvr
Цитата

Глупый вопрос - а сервер точно что-то отправляет? Может и получать нечего?  

да отправляет

Отправляет просто по факту подключения к нему? Я что то не заметил в исходных кодах, что бы твой клиент что-нибудь посылал серверу при подключении.
Попробуй проверить сервер - подключись к нему например telnet'ом

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


Опытный
**


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

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



картина такая.
создат сокет,конекнулся к серверу и послал пакет пока все нормально.
Код

OpenSoket(SOCK_STREAM ,9998,"192.168.0.136");
Connect("192.168.0.136",9998);
OnSend(paket);

потом вызеваю StartThread(); создаю собтие,создаю новый тред и жду ивента на рисив в созданном потоке.
Код

StartThread(...)
{
    m_pSocket = pSocket;
    m_Event[m_EventTotal] = WSACreateEvent();
    ++m_EventTotal;
    WSAEventSelect(m_pSocket->m_hsocket, &m_Event,FD_READ|FD_WRITE);
        m_ThreadHandle = CreateThread(NULL, 0, &ThreadProc, (LPVOID)this, 0, &m_threadID);
}

ThreadProc(LPVOID pVoid)
{
  CSocketThread  &this_ =  *(CSocketThread*)pVoid;
    WSANETWORKEVENTS NetworkEvents;
    memset(&NetworkEvents, 0, sizeof(NetworkEvents));
    while(1)
    {
                
      DWORD dw_Index = WSAWaitForMultipleEvents(this_.m_EventTotal,this_.m_Event,FALSE,WSA_INFINITE,FALSE);
        //...
    }

}


так вот пакет отправлен,поток создан все что надо это получить рисив тогда когда WSAWaitForMultipleEvents(...) сработает..
но он на WSAWaitForMultipleEvents(..) зависает и не какого ответного ивента на рисив не получает.

p.s
может я че то путаю с организацей? 



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

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


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

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



knut, как думаешь - легко в голове сложить все твои отрывки, попробовать догадаться, как ты реализовал то, что рассказываешь "в прозе", добавить недостающее и оценить правильность организации? - и кто будет заниматься подобной ....?! smile
PM MAIL   Вверх
xvr
Дата 10.11.2007, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(knut @ 10.11.2007,  15:16)
картина такая.
создат сокет,конекнулся к серверу и послал пакет пока все нормально.
Код

OpenSoket(SOCK_STREAM ,9998,"192.168.0.136");
Connect("192.168.0.136",9998);
OnSend(paket);


Я что то не нашел в этом коде где ты послал пакет ? Вижу только конект и ожидание приема, передачу чего-либо не вижу.
PM MAIL   Вверх
knut
Дата 10.11.2007, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



dumb
согласен с ясностю поса у меня не так получилось ка xотелос.но я выкладываю всю реализацию выесняется не то. выкладываю куски  опять не то.
мил. человек в чем же дело? 
xvr


Цитата

Я что то не нашел в этом коде где ты послал пакет ? Вижу только конект и ожидание приема, передачу чего-либо не вижу. 


если внимательно посмотреть  на OnSend(paket);  и  пост  номет 1 где реализ. метода OnSend то будет ясность в моем постеsmile
 


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

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


Эксперт
****


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

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



Цитата(knut @ 10.11.2007,  20:43)
xvr


Цитата

Я что то не нашел в этом коде где ты послал пакет ? Вижу только конект и ожидание приема, передачу чего-либо не вижу. 


если внимательно посмотреть  на OnSend(paket);  и  пост  номет 1 где реализ. метода OnSend то будет ясность в моем постеsmile

Посмотрел, увидел отправку пакета в overlapped режиме, но не увидел ожидания окончания отправки (метод есть, но он не вызывается)
Так же неясно, будут ли валидными буфера с содержимым для передачи и overlapped структура до окончания собственно передачи (а они ДОЛЖНЫ быть валидными). Попробуй для начала отправить пакет в не-overlapped режиме (подай NULL вместо указателя на overlapped структуру в WSASend в OnSend)
Так же можно попробовать принять пакет в не-overlapped режиме. Если заработает - ищи ошибку в реализации overlapped режима, иначе - в приеме/передаче/подсоединении.

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


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


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

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



Цитата(knut @  10.11.2007,  20:43 Найти цитируемый пост)
я выкладываю всю реализацию выесняется не то. выкладываю куски  опять не то.
мил. человек в чем же дело? 
Камрад, просто всю реализацию ты так ни разу и не выложил...  Неужто так сложно вырезать из проекта все, что не относится к проблеме, проверить что проблема сохраняется, проект компилируется, запаковать проект в архив и приаттачить к посту? Поверь, скачав архив с проектом, запустив сразу же на исполнение, расставив брейкпойнты на критичные места, получив визуальные данные отладчика и дописав\исправив\удалив необходимые куски кода,  люди нашли бы ответ на твой вопрос гораздо быстрее, чем потратив кучу времени на лепку из твоих кусков кода своего проекта, увидев, что ты забыл выложить объявления каких-то структур и переменных, придумывать свои собственные вместо них и потом еще пытаться найти ответ на необходимый вопрос...
Я вот, к примеру, до сих пор не понял, что за структура такая: PACKET? Может ткнешь меня, где она у тебя тут описана? В штатных виндовых струтктурах у меня её тоже нет...


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

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


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

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


 




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


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

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