Исходные данные. Система, состоящая из ПК (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 - то таймаут }//-пока стоит команда слушат ответы от разных серверов
|
Это кусок в котором собс-но и происходит чтение. ПОвторюсь - при соединении кабелем - все работает. Задача имеет коммерческий интерес - поэтому если кто-то имеет соотв. опыт и желание подзаработать - обращайтесь.
|