C ++経由のspeedtest.net

以下のコードはすべて、私の最近のプロジェクトの1つからの抜粋です。このフレームワーク内では、ダウンロードとアップロードの速度を決定する必要がありました。 自転車の発明には消極的だったので、このタイプのサービスの中で最も尊敬され効率的なサービスwww.speedtest.netを使用したいという要望がありました。 しかし、練習が示すように、彼は完全に非友好的であり、まだ自転車を発明しなければなりませんでした。







そこで、私はGoogleを掘り下げることから作業のこの部分を開始し、1つの興味深いリンクを見つけました-http: //speedtest.net/speedtest-config.php、かなり大きなXMLコードをロードします。



  1. <?xml version = "1.0" encoding = "UTF-8" ?> <settings > <client ip = "*.*.*.*" lat = "60.0000" lon = "100.0000" isp = "Samara Telecom, JSC" isprating = "3.3" rating = "5" ispdlavg = "4449" ispulavg = "1394" /> <licensekey > 9c1687ea58e5e770-1df5b7cd427370f7-4b62a84526ea1f56 </licensekey > <customer > speedtest </customer > <servers > <server url = "http://speedtest.pronea.no/speedtest/upload.php" lat = "69.6828" lon = "18.9428" name = "Tromso" country = "Norway" countrycode = "NO" sponsor = "Pronea AS" sponsorurl = "http://www.pronea.no/" id = "1327" gid = "0" bigsamples = "1" /> <server url = "http://test.nax.no/speedtest/upload.php" lat = "65.8333" lon = "13.2000" name = "Helgeland" country = "Norway" countrycode = "NO" sponsor = "Noraxess Broadband" sponsorurl = "http://www.nax.no" id = "1362" gid = "0" url2 = "http://85.221.66.41/speedtest/upload.php" bigsamples = "1" />



  2. <?xml version = "1.0" encoding = "UTF-8" ?> <settings > <client ip = "*.*.*.*" lat = "60.0000" lon = "100.0000" isp = "Samara Telecom, JSC" isprating = "3.3" rating = "5" ispdlavg = "4449" ispulavg = "1394" /> <licensekey > 9c1687ea58e5e770-1df5b7cd427370f7-4b62a84526ea1f56 </licensekey > <customer > speedtest </customer > <servers > <server url = "http://speedtest.pronea.no/speedtest/upload.php" lat = "69.6828" lon = "18.9428" name = "Tromso" country = "Norway" countrycode = "NO" sponsor = "Pronea AS" sponsorurl = "http://www.pronea.no/" id = "1327" gid = "0" bigsamples = "1" /> <server url = "http://test.nax.no/speedtest/upload.php" lat = "65.8333" lon = "13.2000" name = "Helgeland" country = "Norway" countrycode = "NO" sponsor = "Noraxess Broadband" sponsorurl = "http://www.nax.no" id = "1362" gid = "0" url2 = "http://85.221.66.41/speedtest/upload.php" bigsamples = "1" />



  3. <?xml version = "1.0" encoding = "UTF-8" ?> <settings > <client ip = "*.*.*.*" lat = "60.0000" lon = "100.0000" isp = "Samara Telecom, JSC" isprating = "3.3" rating = "5" ispdlavg = "4449" ispulavg = "1394" /> <licensekey > 9c1687ea58e5e770-1df5b7cd427370f7-4b62a84526ea1f56 </licensekey > <customer > speedtest </customer > <servers > <server url = "http://speedtest.pronea.no/speedtest/upload.php" lat = "69.6828" lon = "18.9428" name = "Tromso" country = "Norway" countrycode = "NO" sponsor = "Pronea AS" sponsorurl = "http://www.pronea.no/" id = "1327" gid = "0" bigsamples = "1" /> <server url = "http://test.nax.no/speedtest/upload.php" lat = "65.8333" lon = "13.2000" name = "Helgeland" country = "Norway" countrycode = "NO" sponsor = "Noraxess Broadband" sponsorurl = "http://www.nax.no" id = "1362" gid = "0" url2 = "http://85.221.66.41/speedtest/upload.php" bigsamples = "1" />



  4. <?xml version = "1.0" encoding = "UTF-8" ?> <settings > <client ip = "*.*.*.*" lat = "60.0000" lon = "100.0000" isp = "Samara Telecom, JSC" isprating = "3.3" rating = "5" ispdlavg = "4449" ispulavg = "1394" /> <licensekey > 9c1687ea58e5e770-1df5b7cd427370f7-4b62a84526ea1f56 </licensekey > <customer > speedtest </customer > <servers > <server url = "http://speedtest.pronea.no/speedtest/upload.php" lat = "69.6828" lon = "18.9428" name = "Tromso" country = "Norway" countrycode = "NO" sponsor = "Pronea AS" sponsorurl = "http://www.pronea.no/" id = "1327" gid = "0" bigsamples = "1" /> <server url = "http://test.nax.no/speedtest/upload.php" lat = "65.8333" lon = "13.2000" name = "Helgeland" country = "Norway" countrycode = "NO" sponsor = "Noraxess Broadband" sponsorurl = "http://www.nax.no" id = "1362" gid = "0" url2 = "http://85.221.66.41/speedtest/upload.php" bigsamples = "1" />



  5. <?xml version = "1.0" encoding = "UTF-8" ?> <settings > <client ip = "*.*.*.*" lat = "60.0000" lon = "100.0000" isp = "Samara Telecom, JSC" isprating = "3.3" rating = "5" ispdlavg = "4449" ispulavg = "1394" /> <licensekey > 9c1687ea58e5e770-1df5b7cd427370f7-4b62a84526ea1f56 </licensekey > <customer > speedtest </customer > <servers > <server url = "http://speedtest.pronea.no/speedtest/upload.php" lat = "69.6828" lon = "18.9428" name = "Tromso" country = "Norway" countrycode = "NO" sponsor = "Pronea AS" sponsorurl = "http://www.pronea.no/" id = "1327" gid = "0" bigsamples = "1" /> <server url = "http://test.nax.no/speedtest/upload.php" lat = "65.8333" lon = "13.2000" name = "Helgeland" country = "Norway" countrycode = "NO" sponsor = "Noraxess Broadband" sponsorurl = "http://www.nax.no" id = "1362" gid = "0" url2 = "http://85.221.66.41/speedtest/upload.php" bigsamples = "1" />



  6. <?xml version = "1.0" encoding = "UTF-8" ?> <settings > <client ip = "*.*.*.*" lat = "60.0000" lon = "100.0000" isp = "Samara Telecom, JSC" isprating = "3.3" rating = "5" ispdlavg = "4449" ispulavg = "1394" /> <licensekey > 9c1687ea58e5e770-1df5b7cd427370f7-4b62a84526ea1f56 </licensekey > <customer > speedtest </customer > <servers > <server url = "http://speedtest.pronea.no/speedtest/upload.php" lat = "69.6828" lon = "18.9428" name = "Tromso" country = "Norway" countrycode = "NO" sponsor = "Pronea AS" sponsorurl = "http://www.pronea.no/" id = "1327" gid = "0" bigsamples = "1" /> <server url = "http://test.nax.no/speedtest/upload.php" lat = "65.8333" lon = "13.2000" name = "Helgeland" country = "Norway" countrycode = "NO" sponsor = "Noraxess Broadband" sponsorurl = "http://www.nax.no" id = "1362" gid = "0" url2 = "http://85.221.66.41/speedtest/upload.php" bigsamples = "1" />



  7. <?xml version = "1.0" encoding = "UTF-8" ?> <settings > <client ip = "*.*.*.*" lat = "60.0000" lon = "100.0000" isp = "Samara Telecom, JSC" isprating = "3.3" rating = "5" ispdlavg = "4449" ispulavg = "1394" /> <licensekey > 9c1687ea58e5e770-1df5b7cd427370f7-4b62a84526ea1f56 </licensekey > <customer > speedtest </customer > <servers > <server url = "http://speedtest.pronea.no/speedtest/upload.php" lat = "69.6828" lon = "18.9428" name = "Tromso" country = "Norway" countrycode = "NO" sponsor = "Pronea AS" sponsorurl = "http://www.pronea.no/" id = "1327" gid = "0" bigsamples = "1" /> <server url = "http://test.nax.no/speedtest/upload.php" lat = "65.8333" lon = "13.2000" name = "Helgeland" country = "Norway" countrycode = "NO" sponsor = "Noraxess Broadband" sponsorurl = "http://www.nax.no" id = "1362" gid = "0" url2 = "http://85.221.66.41/speedtest/upload.php" bigsamples = "1" />







さらに、すべてのxmlは、speedtestサーバーコンポーネントがインストールされているサーバーのリストです。 緯度と経度のパラメータは緯度と経度、つまり緯度と経度にすぎないことに気づいたとき、手で自分に最も近いサーバーを見つけなければなりませんでした-私は冷や汗をかきました。 「グライム」と思ったので、大きなC ++の魔法が始まりました。



_sendPacket関数は、httpパッケージの単純な構造であり、それ自体に科学的な関心を持たないため、許可を得てスキップします。 _getConfigに直行しましょう。



  1. void _getConfig ( )
  2. {
  3. std :: stringstream netspeedConfigStream = _sendPacket ( _SpeedtestServer、_SpeedtestConfigUrl ) ;
  4. //空のプロパティツリーオブジェクトを作成します
  5. boost :: property_tree :: ptreeを使用し ます。
  6. ptree PropertyTree ;
  7. // XMLファイルを読み込み、その内容をプロパティツリーに配置します。
  8. // Koenigのため、名前空間の修飾は必要ありません
  9. // 2番目の引数を検索します。 読み取りに失敗した場合、例外
  10. //スローされます。
  11. read_xml ( netspeedConfigStream、PropertyTree ) ;
  12. ptree設定= PropertyTree。 get_child ( "settings" ) ;
  13. //クライアントの場所を構築します
  14. _ServerLocation * _ClientLocation ;
  15. //サーバーの場所のリストを宣言します
  16. std :: vector < _ServerLocation > * _ServerLocationList ;
  17. _ClientLocation = new _ServerLocation ( Settings。Begin ( ) - > second、 false ) ;
  18. _ServerLocationList = new std :: vector < _ServerLocation > ;
  19. // XMLからリストを構築します
  20. BOOST_FOREACH ( ptree :: value_type & v、PropertyTree。Get_child ( "settings.servers" ) )
  21. _ServerLocationList- > push_back ( _ServerLocation ( v。Second、 true ) ) ;
  22. std :: sort ( _ServerLocationList- > begin ( ) 、_ ServerLocationList- > end ( ) 、_ ServerLocationSortFunctor ( _ClientLocation ) )) ;
  23. //最も近いサーバーのURL
  24. std :: vector < std :: string > SplitUrl ;
  25. boost :: split ( SplitUrl、_ServerLocationList- > begin ( ) - > GetUrl ( ) 、boost :: is_any_of ( "/" ) ) ;
  26. _ClientLocationを削除します。
  27. _ServerLocationListを削除します。
  28. _NearestServer = SplitUrl [ 2 ] ;
  29. for ( int i = 3 ; i < SplitUrl。size ( ) - 1 ; ++ i ) // TODO:イテレータで書き換える
  30. {
  31. _NearestServerUrl。 追加 ( "/" ) ;
  32. _NearestServerUrl。 append ( SplitUrl [ i ] ) ;
  33. }
  34. 帰る
  35. }




コードからわかるように、XMLを受信して​​から解析し、_ServerLocation構造体のベクターに入力しています。 自転車の暴力に抵抗しないように、最も近いサーバーの検索は、STL-ev sortを呼び出すことによって行われました。このために、ソートファンクターを作成する必要がありました。



  1. struct _ServerLocationSortFunctor
  2. {
  3. 公開 :
  4. _ServerLocationSortFunctor ( _ServerLocation * ClientLocation ) : _ClientLocation ( ClientLocation ) { }
  5. bool演算子( ) ( _ServerLocation & _First、_ServerLocation & _Second )
  6. {
  7. return _ServerDist ( _ClientLocation、 & _First ) < _ServerDist ( _ClientLocation、 & _Second ) ;
  8. }
  9. プライベート :
  10. _ServerLocation * _ClientLocation ;
  11. インライン double deg2rad ( double ServerAplpha )
  12. {
  13. ServerAplpha * PI / 180を 返し ます。
  14. }
  15. インライン 二重 hypot3 ( 二重 dx、 二重 dy、 二重 dz )
  16. {
  17. return sqrt ( dx * dx + dy * dy + dz * dz ) ;
  18. }
  19. double _ServerDist ( _ServerLocation * _First、_ServerLocation * _Second )
  20. {
  21. double phi1 = deg2rad ( _First- > GetLon ( ) ) ;
  22. double psi1 = deg2rad ( _First- > GetLat ( ) ) ;
  23. double phi2 = deg2rad ( _Second- > GetLon ( ) ) ;
  24. double psi2 = deg2rad ( _Second- > GetLat ( ) ) ;
  25. double cos_psi1 = cos ( psi1 ) ;
  26. double x1 = EarthRadius * cos ( phi1 ) * cos_psi1 ;
  27. double y1 = EarthRadius * sin ( phi1 ) * cos_psi1 ;
  28. double z1 = EarthRadius * sin ( psi1 ) ;
  29. double cos_psi2 = cos ( psi2 ) ;
  30. double x2 = EarthRadius * cos ( phi2 ) * cos_psi2 ;
  31. double y2 = EarthRadius * sin ( phi2 ) * cos_psi2 ;
  32. double z2 = EarthRadius * sin ( psi2 ) ;
  33. double d = hypot3 ( x2 - x1、y2 - y1、z2 - z1 ) ;
  34. EarthRadius * acos ( 1- ( d * d ) / ( 2 * EarthRadius * EarthRadius ) ) ;
  35. }
  36. } ;




学校のコースは地理または幾何学のいずれかであり、最も近いサーバーが見つかりました。



さらに、速度測定コード自体は簡単なので、それほど面白くなりません。

  1. void _testLatency ( )
  2. {
  3. std :: string Url ( _NearestServerUrl ) ;
  4. URL append ( _LatencyUrl ) ;
  5. boost :: タイマー LatencyTimer ;
  6. _sendPacket ( _NearestServer、Url ) ;
  7. _LatencyTime = LatencyTimer。 経過 ( ) ;
  8. std :: cout << "PING:" << _LatencyTime << std :: endl ;
  9. 帰る
  10. }
  11. void _testDownload ( )
  12. {
  13. std :: string Url ( _NearestServerUrl ) ;
  14. URL append ( _DownloadUrl ) ;
  15. boost :: タイマー DownloadTimer ;
  16. std :: stringstream DownloadPacket = _sendPacket ( _NearestServer、Url ) ;
  17. double DownloadTime = DownloadTimer。 経過 ( ) ;
  18. double DownloadSpeed = ( DownloadPacket.str ( ) 。 length ( ) / ( DownloadTime - _LatencyTime ) )) * 8/1024 ;
  19. std :: cout << "DOWNLOAD:" << DownloadSpeed << std :: endl ;
  20. 帰る
  21. }
  22. void _testUpload ( )
  23. {
  24. std :: string Url ( _NearestServerUrl ) ;
  25. URL append ( _UploadUrl ) ;
  26. std :: string UploadDataValue ( _UploadBytes、 'a' ) ;
  27. std :: string UploadData ( "content0 =" ) ;
  28. UploadData + = UploadDataValue ;
  29. boost :: タイマー UploadTimer ;
  30. _sendPacket ( _NearestServer、Url、 true 、UploadData ) ;
  31. double UploadTime = UploadTimer。 経過 ( ) ;
  32. double UploadSpeed = ( _UploadBytes / ( UploadTime - _LatencyTime ) ) * 8/1024 ;
  33. std :: cout << "UPLOAD:" << UploadSpeed << std :: endl ;
  34. }




たぶん誰かが役に立つでしょう。 コードはVisual Studio 2010でテストされました(プロジェクトの残りの部分はWindowsで強化されました)。



私は、STLとBoostのドキュメントに加えて、自習用にインターネットで見つけたソースコードの一部に感謝したいと思います。



このopusの完全なコードは、 http: //paste.pocoo.org/show/215424/で入手できます。

______________________

テキストは©SoftCoder.ruによってブログエディターで作成されます。



All Articles