Модераторы: 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   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "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.1020 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


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

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