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