Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема с wi-fi связью, с кабелем все ок, а с wi-fi - глюки 
:(
    Опции темы
Zhaw
Дата 11.9.2007, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Исходные данные.
Система, состоящая из ПК (win xp) и устройство (на базе PXA-270 - linux debian). ПК инициирует обмен пакетами по 32 байта, устройство отвечает такими же пакетами (32 байта), и по некоторым событиям (нажатие кнопки на устройстве) происходит обмен данными (4096 байт) от устройства к ПК. При соединении устройств просто витой парой - все ок, все работает и передается. Теперь надо вместо витой пары подключить wireless адаптер. Подключили с одной стороны ASUS WL330g (к устройству) с другой (к ПК) TRENDNet TEW-509UB. Настроили все в режим прозрачности (Ad-Hoc) -  получается следующий глюк. Где-то раз за 10-20 посылок (обменов по 32 байта) очередной пакет отправляется с устройства на ПК (видно через отчет программы устройства через telnet) но на ПК функция чтения (select) возвращает тайм-аут (установлен в 1-2-4 секунды). При следующих засылках начинают приниматься ранее "застрявшие". Сетевой сниффер показывает, что все пакеты на комп пришли, а вот с сокета ..... не доходят - застревают. 
Вот пример считывания 
Код

//----------отослали пакет - теперь будем принимать ответы от устройств (дефектоскопов)------
  bKeepListening = true;
   while (bKeepListening)
  { //-пока стоит команда - слушать ответы
        FD_ZERO(&SocketListening);
        FD_SET(ClientMainSocket, &SocketListening);
        /* This must be reset every time select() is called */
        selTimeout.tv_sec = 2; /* timeout (secs.) */
        selTimeout.tv_usec = 0; /* microseconds */
        bKeepReceiving = TRUE;
    
    if (select ((int)(ClientMainSocket+1),&SocketListening,NULL,NULL,&selTimeout) > 0)
    { //-если что-то проявилось на сокетах------
    if (FD_ISSET (ClientMainSocket,&SocketListening)) 
    { //-если проявилось именно на нашем сокете

      while (bKeepReceiving)
      {//-while (bKeepReceiving)
    // Receive data from the server socket.
         iAddrLength = sizeof(SOCKADDR);
         saReceivedAddr.sin_port = htons(IP_PORT);
         saReceivedAddr.sin_family = AF_INET;    
         saReceivedAddr.sin_addr.S_un.S_addr = htons(INADDR_ANY);
         iReturn = recvfrom (ClientMainSocket, cReceiveBuff/*CurrAccessNode->cDataArray*/, COMMAND_LENGTH/*CurrAccessNode->cDataArrayLength*/, 0,(SOCKADDR*)&saReceivedAddr,&iAddrLength);
            //-----слушаем реакцию сокета - функция возвращается по таймауту либо по событиюю приема данных
         //---
          if (iReturn == SOCKET_ERROR)
          {//-if (iReturn == SOCKET_ERROR) - если ошибка на сокете
              i = WSAGetLastError ();
              if (i != WSAEWOULDBLOCK)
              { //-если реально ОШИБКА - то вываливаемся с собщением не могу прочитать данные
                delete [](cReceiveBuff);
                if (i == 10040)
                {//-сообщение о том, что не хватило места на прием 
                    return SER_RCV_ARR_TOO_SMALL; //-и вываливаемся с сообщением об ошибке
                } //-сообщение о том, что не хватило места на прием 
                else
                {
                    return SER_CANT_READ_DATA; //-и вываливаемся с сообщением об ошибке
                }
              }
              else
              { //-если просто сообщение о возможности блока - продолжаем прием

              };
        }//-if (iReturn == SOCKET_ERROR) - если ошибка на сокете
          else
       { //-если на сокете нету ошибок
          bKeepReceiving = FALSE; //-то прекращаем прием и начинаем рассматривать что мы приняли
       } //-если на сокете нету ошибок
      }//-while (bKeepReceiving)
        //-обработка ответов зависит от адреса отправления - дл яуказанного алдреса - одна, для броадкаста - другая--------
      if (_sTargetNode == BROADCAST_NODE_NUMBER)
      {//-для броадкаста - собираем все ответы по их нодам (ответить могут все)
        if (SetNodePointersbyAddress (saReceivedAddr,&CurrAccessNode,&CurrNode) == OPERATION_SUCCESS)
        {
            if (CopyDataFromArraytoNode ((unsigned char *)cReceiveBuff,iReturn,CurrAccessNode->sNodeAccessNumber) == OPERATION_SUCCESS)
            {
                CurrAccessNode->cNewData = NEW_DATA_AVAILABLE;
                bOperationSuccesfull = true;
            }
            else
            {
                return SER_RCV_ARR_TOO_SMALL;
                bOperationSuccesfull = false;
            };
        }
        else
        {
            return NODE_NUMBER_NA;
            bOperationSuccesfull = false;
        }
        //-вываливаемся из броадкаста - только по таймауту - слушаем "до последнего"
      } //-для броадкаста - собираем все ответы по их нодам (ответить могут все)
      else
      { //-для единичного адресата - слушаем только егго
        if ((saReceivedAddr.sin_addr.S_un.S_addr == CurrNode->adrNodeAddres.sin_addr.S_un.S_addr))
        { //-если адрес ответившего устройства совпадает с указанным - то все парвильно - мы приняли нужный ответ
            if (CopyDataFromArraytoNode ((unsigned char *)cReceiveBuff,iReturn,CurrAccessNode->sNodeAccessNumber) == OPERATION_SUCCESS)
            {
                CurrAccessNode->cNewData = NEW_DATA_AVAILABLE;
                bOperationSuccesfull = true;
            }
            else
            {
                return SER_RCV_ARR_TOO_SMALL;
                bOperationSuccesfull = false;
            };
            bKeepListening = FALSE;  //-то больше не слушаем ничего и выходим
        }; //-если адрес ответившего устройства совпадает с указанным - то все парвильно - мы приняли нужный ответ
      };//-для единичного адресата - слушаем только егго

        //-----------
    } //-если проявилось именно на нашем сокете
    } //-если что-то проявилось на сокете
    else
    { //-если вернулся 0 - то таймаут
        cTOutsCounter ++;
        if (cTOutsCounter > 1)
        {
            bKeepListening = FALSE; 
            return SER_TIMEOUT_READING;
        }
        else
            bKeepListening = TRUE; 
    }//-если вернулся 0 - то таймаут
  }//-пока стоит команда слушат ответы от разных серверов

Это кусок в котором собс-но и происходит чтение.
ПОвторюсь - при соединении кабелем - все работает.

Задача имеет коммерческий интерес - поэтому если кто-то имеет соотв. опыт и желание подзаработать - обращайтесь.
PM MAIL   Вверх
Zhaw
Дата 4.10.2007, 09:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Решение найдено путем внимательного прочтения MSDN - для случаев с bluetooth (wi-fi тоже) и IRdA - использовать ТОЛЬКО stream-сокеты - и все работает (ну дополнительные меры для реконнекта сокетов - если очень тяжелые условия работы).
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




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


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

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