Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.223.119.17] |
|
Сообщ.
#1
,
|
|
|
ApplicationManager am; //NetworkManager nm; try { IGDDiscoverProcess discoverer( 500000 ); tg.create_thread( boost::ref( discoverer ) ); tg.join_all(); IGDDiscoverProcess::IGDControlInformations cinfos = discoverer.GetAllIGDControlInformations(); boost_foreach( IGDDiscoverProcess::ControlInfo info, cinfos ) { //::MessageBoxA(NULL,info.service_type.c_str(),CStringA("info.service_type"),MB_ICONINFORMATION); if( info.has_problem ) { continue; } if( info.service_type == UPNPSERVICE_LAYER3FORWARDING1 ) { UPNPNATHTTPClient soap( info.ip, info.port ); soap.GetDefaultConnectionService( info.control_url, info.service_type ); } else if( info.service_type == UPNPSERVICE_WANIPCONNECTION1) { UPNPNATHTTPClient soap( info.ip, info.port ); std::string ip; UPNPNATHTTPClient::SoapResult res = soap.GetWANIPAddress( ip, info.control_url, info.service_type ); if(ip.length()!=0) { list_external_ip_4.AddString(CString(ip.c_str())); } } else if( info.service_type == UPNPSERVICE_WANCOMMONINTERFACECONFIG1 ) { } else if(info.service_type == UPNPSERVICE_WANPPPCONNECTION1) { UPNPNATHTTPClient soap( info.ip, info.port ); std::string ip; UPNPNATHTTPClient::SoapResult res = soap.GetWANIPAddress( ip, info.control_url, info.service_type ); if(ip.length()!=0) { list_external_ip_4.AddString(CString(ip.c_str())); } } } } catch( IGDDiscoverProcess::exception &e ) { CString error(e.what()); } IGDDiscoverProcess::IGDDiscoverResult IGDDiscoverProcess::Receive( string &igdip, string &data ) { int res(0); fd_set read_fds; FD_ZERO( &read_fds ); FD_SET( pimpl->sock, &read_fds ); res = select( pimpl->sock+1, &read_fds, NULL, NULL, &pimpl->msearch_timeout ); if( 0 == res ) { // timeouted return Timeout; } if( FD_ISSET( pimpl->sock, &read_fds ) ) { char buff[BUFFER_SIZE] = {0}; sockaddr_in from = {0}; int from_len = static_cast<int>(sizeof(from)); int received = recvfrom( pimpl->sock, buff, sizeof(buff), 0, (sockaddr*)&from, &from_len ); if( SOCKET_ERROR == received ) { BHDebug( false, L"recv error." ); return SocketError; } if( received < BUFFER_SIZE-2 ) { igdip.assign( inet_ntoa( from.sin_addr ) ); buff[received] = '\0'; data.assign( buff ); } else { // too long data return TooLongData; } return Succeeded; } return Failed; } IGDDiscoverProcess::IGDDiscoverResult IGDDiscoverProcess::MSearch( const std::string &service_type ) { Impl::Manager connection( this ); // RAII object string data( MSEARCH_REQUEST ); data += service_type; data += "\r\n\r\n"; IGDDiscoverResult res; // sending m-search to all nics that have found. boost_foreach( const in_addr &to, pimpl->ips ) { res = Send( data, to ); if( Succeeded != res ) aconsole( boost::str( boost::format("failed to send %s m-search.")%service_type.c_str()) ); } // receiving and extracting upnp-igd control informations // from responces string igdip; string received; while( Succeeded == (res = Receive( igdip, received)) ) { ControlInfo cinfo; int httpres(0); res = ExtractControlInfo( received, cinfo, httpres ); if( Succeeded != res ) { aconsole(boost::str(boost::format( "failed to ExtractControlInfo on [NIC:...]" ))); continue; } else { if( !ExistedControlInfomation( cinfo ) ) { pimpl->igd_infos.push_back( cinfo ); } } } return Failed; } Когда в отладке выполняешь функцию по шагам IGDDiscoverProcess::IGDDiscoverResult IGDDiscoverProcess::MSearch, тогда находит службу const std::string UPNPSERVICE_WANIPCONNECTION1 = std::string( "urn:schemas-upnp-org:service:WANIPConnection:1" ); Может найти ещё и службы const std::string UPNPSERVICE_LAYER3FORWARDING1 = std::string( "urn:schemas-upnp-org:service:Layer3Forwarding:1" ); const std::string UPNPSERVICE_WANCOMMONINTERFACECONFIG1 = std::string( "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" ); Когда выполняешь без точек остановки, тогда находит службы const std::string UPNPSERVICE_LAYER3FORWARDING1 = std::string( "urn:schemas-upnp-org:service:Layer3Forwarding:1" ); const std::string UPNPSERVICE_WANCOMMONINTERFACECONFIG1 = std::string( "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" ); Думаю, что разница либо в синхронизации потоков, либо в ошибке получения данных от указанного модема. Зависает при приёме данных от модема. Видимо в данном модеме приём и отправки идут в одном потоке и может его микропрограмма вообще однопоточная. С модемами ZyXEL Keenetic Dsl и TP-Link программа работает нормально. Код для работы с UPnP взял из старого проекта с codeproject и переделал до собираемого состояния, исправил ошибки поиска в xml названий служб и их описаний. Какие есть идеи? Добавлено std::string UPNPNATHTTPClient::ReceiveResponce( void ) { std::string res; char buff[MAX_BUFFER] = {0}; int received(0); timeval timeout = {0}; timeout.tv_sec = 10; fd_set rfds; FD_ZERO( &rfds ); FD_SET( pimpl->http_sock, &rfds ); int err = select( pimpl->http_sock, &rfds, NULL, NULL, &timeout ); if( 0 == err ) { return string(""); } if( FD_ISSET( pimpl->http_sock, &rfds ) ) { while( received = recv( pimpl->http_sock, buff, sizeof(buff), 0 ) > 0 ) { res += buff; memset( buff, 0, sizeof(buff) ); if(received<MAX_BUFFER) { //break; } } } //cout << res; return res; } Зависает в строке while( received = recv( pimpl->http_sock, buff, sizeof(buff), 0 ) > 0 ) Добавлено Тут устанавливаются тайм ауты. И возможно на тайм аутах зависает и/или received всегда > 0. Но на нормальных же модемах работает. Добавлено Ещё и служба dns на этом Bilion не работает толком. И при отладке по точкам остановки находит службы, но потом зависает в этом цикле получения данных от модема на выполнении команд через UPnP. Добавлено Какие есть идеи? |