Commit 809d7a9c authored by captainwong's avatar captainwong

add net/resolve_fastest_ip.h

parent 43f89c3a
......@@ -28,17 +28,19 @@ static constexpr char g_logger_name[] = "jlogger";
inline void init_logger(
#ifdef JLIB_WINDOWS
std::wstring
std::wstring file_name = L""
#else
std::string
std::string file_name = ""
#endif
file_name)
)
{
if (!file_name.empty()) {
#ifdef JLIB_WINDOWS
file_name += L".log";
#else
file_name += ".log";
#endif
}
try {
std::vector<spdlog::sink_ptr> sinks;
......@@ -46,9 +48,9 @@ file_name)
sinks.push_back(std::make_shared<spdlog::sinks::msvc_sink_mt>());
#endif
sinks.push_back(std::make_shared<spdlog::sinks::stdout_sink_mt>());
sinks.push_back(std::make_shared<spdlog::sinks::daily_file_sink_mt>(
file_name , 23, 59));
if (!file_name.empty()) {
sinks.push_back(std::make_shared<spdlog::sinks::daily_file_sink_mt>(file_name, 23, 59));
}
auto combined_logger = std::make_shared<spdlog::logger>(g_logger_name, begin(sinks), end(sinks));
combined_logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%t] [%L] %v");
spdlog::register_logger(combined_logger);
......
......@@ -17,6 +17,7 @@ namespace net {
class pinger
{
public:
typedef boost::asio::ip::icmp icmp;
typedef boost::asio::deadline_timer deadline_timer;
typedef std::function<void(const std::string&)> Output;
......@@ -75,7 +76,7 @@ private:
time_sent_ = boost::posix_time::microsec_clock::universal_time();
socket_.send_to(request_buffer.data(), destination_);
// Wait up to five seconds for a reply.
// Wait up to 3 seconds for a reply.
num_replies_ = 0;
timer_.expires_at(time_sent_ + boost::posix_time::seconds(3));
timer_.async_wait(boost::bind(&pinger::handle_timeout, this));
......@@ -83,7 +84,7 @@ private:
void handle_timeout() {
if (num_replies_ == 0) {
total_time_ += std::chrono::milliseconds(5000);
total_time_ += std::chrono::milliseconds(3000);
output_("Request timed out");
}
......
#pragma once
#include "../log2auto.h"
#include "ping.h"
namespace jlib {
namespace net {
using waiting_cb = std::function<void(void)>;
namespace detail {
static std::pair<long long, std::string> pingIpGetAverageMs(const std::string& ip, int ping_times, jlib::net::pinger::Output output)
{
boost::asio::io_service io_service;
JLOG_INFO("ping ip:{}", ip);
jlib::net::pinger p(io_service, ip.c_str(), ping_times, output);
io_service.run();
auto ms = p.get_average();
JLOG_INFO("ip:{} 's average delay is {}ms", ip, ms);
return { ms, ip };
}
static std::pair<bool, std::string> get_domain_ip_impl(const std::string& domain, int ping_times) {
AUTO_LOG_FUNCTION;
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query(domain, "");
try {
std::string fastest_ip;
std::vector<std::string> ips;
long long fastest_ping_ms = 500000000;
JLOG_INFO("resolving domain:{}", domain);
auto iter = resolver.resolve(query);
boost::asio::ip::tcp::resolver::iterator end;
while (iter != end) {
boost::asio::ip::tcp::endpoint endpoint = *iter++;
std::string ip = endpoint.address().to_string();
ips.push_back(ip);
}
std::vector<std::future<std::pair<long long, std::string>>> threads;
for (auto ip : ips) {
threads.emplace_back(std::async(std::launch::async, pingIpGetAverageMs, ip, ping_times, [](const std::string& msg) {
JLOG_INFO(msg);
}));
}
bool allDone = true;
while (!allDone) {
allDone = true;
for (auto& f : threads) {
auto status = f.wait_for(std::chrono::milliseconds(1));
if (status != std::future_status::ready) {
allDone = false;
}
}
}
for (auto& f : threads) {
auto res = f.get();
if (res.first < fastest_ping_ms) {
fastest_ping_ms = res.first;
fastest_ip = res.second;
}
}
JLOG_INFO("fastest ip of domain:{} is {}", domain, fastest_ip);
return std::pair<bool, std::string>(true, fastest_ip);
} catch (std::exception& e) {
return std::pair<bool, std::string>(false, e.what());
}
}
} // end of namespace detail
static bool get_domain_ip(const std::string& domain, int ping_times, std::string& result, waiting_cb cb) {
auto f = std::async(std::launch::async, detail::get_domain_ip_impl, domain, ping_times);
while (true) {
auto status = f.wait_for(std::chrono::milliseconds(1));
if (status == std::future_status::ready) {
break;
} else {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
if (cb) { cb(); }
}
}
auto ret = f.get();
result = ret.second;
return ret.first;
}
}
}
......@@ -14,8 +14,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "jlib", "jlib", "{42703978-A
..\jlib\dp.h = ..\jlib\dp.h
..\jlib\log.h = ..\jlib\log.h
..\jlib\log2.h = ..\jlib\log2.h
..\jlib\log2auto.h = ..\jlib\log2auto.h
..\jlib\log2micros.h = ..\jlib\log2micros.h
..\jlib\net.h = ..\jlib\net.h
..\jlib\no_log.h = ..\jlib\no_log.h
..\jlib\utf8.h = ..\jlib\utf8.h
EndProjectSection
EndProject
......@@ -294,6 +295,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_strutil", "test_struti
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_monitor", "test_monitor\test_monitor.vcxproj", "{5EA0AFE3-134D-4573-B8E7-ADEC802722DF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "net_tests", "net_tests", "{77DBD16D-112C-448D-BA6A-CE566A9331FC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_resolve_fastest_ip", "test_resolve_fastest_ip\test_resolve_fastest_ip.vcxproj", "{65F9D4DA-BC6C-486D-8966-6ACCE077639D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
......@@ -600,6 +605,14 @@ Global
{5EA0AFE3-134D-4573-B8E7-ADEC802722DF}.Release|x64.Build.0 = Release|x64
{5EA0AFE3-134D-4573-B8E7-ADEC802722DF}.Release|x86.ActiveCfg = Release|Win32
{5EA0AFE3-134D-4573-B8E7-ADEC802722DF}.Release|x86.Build.0 = Release|Win32
{65F9D4DA-BC6C-486D-8966-6ACCE077639D}.Debug|x64.ActiveCfg = Debug|x64
{65F9D4DA-BC6C-486D-8966-6ACCE077639D}.Debug|x64.Build.0 = Debug|x64
{65F9D4DA-BC6C-486D-8966-6ACCE077639D}.Debug|x86.ActiveCfg = Debug|Win32
{65F9D4DA-BC6C-486D-8966-6ACCE077639D}.Debug|x86.Build.0 = Debug|Win32
{65F9D4DA-BC6C-486D-8966-6ACCE077639D}.Release|x64.ActiveCfg = Release|x64
{65F9D4DA-BC6C-486D-8966-6ACCE077639D}.Release|x64.Build.0 = Release|x64
{65F9D4DA-BC6C-486D-8966-6ACCE077639D}.Release|x86.ActiveCfg = Release|Win32
{65F9D4DA-BC6C-486D-8966-6ACCE077639D}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......@@ -643,7 +656,7 @@ Global
{65C310A4-DAA5-4D94-91B3-848F4E5F5C17} = {0E6598D3-602D-4552-97F7-DC5AB458D553}
{704FF7EB-D633-4D0A-957B-01D908478D6D} = {ABCB8CF8-5E82-4C47-A0FC-E82DF105DF99}
{EAAE08F7-6CD8-4708-9FD4-ADD856CC6658} = {21DC893D-AB0B-48E1-9E23-069A025218D9}
{26D2B628-713F-419A-B2E2-32BDFA803E3C} = {21DC893D-AB0B-48E1-9E23-069A025218D9}
{26D2B628-713F-419A-B2E2-32BDFA803E3C} = {77DBD16D-112C-448D-BA6A-CE566A9331FC}
{2252B5D4-2D13-4F02-8008-AB2E0D38A154} = {D9BC4E5B-7E8F-4C86-BF15-CCB75CBC256F}
{7DC0D84B-7F96-4BB9-9B8A-D86B7B031E61} = {D9BC4E5B-7E8F-4C86-BF15-CCB75CBC256F}
{58DA7AE8-9975-4F28-A1BF-44A7C01B6F7F} = {D9BC4E5B-7E8F-4C86-BF15-CCB75CBC256F}
......@@ -667,6 +680,8 @@ Global
{41C26D67-0174-41AC-850E-1F84181138E5} = {729A65CE-3F07-4C2E-ACDC-F9EEC6477F2A}
{0C743CE7-E49C-47F8-BC53-13929EA5CDA3} = {ABCB8CF8-5E82-4C47-A0FC-E82DF105DF99}
{5EA0AFE3-134D-4573-B8E7-ADEC802722DF} = {0E6598D3-602D-4552-97F7-DC5AB458D553}
{77DBD16D-112C-448D-BA6A-CE566A9331FC} = {21DC893D-AB0B-48E1-9E23-069A025218D9}
{65F9D4DA-BC6C-486D-8966-6ACCE077639D} = {77DBD16D-112C-448D-BA6A-CE566A9331FC}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A8EBEA58-739C-4DED-99C0-239779F57D5D}
......
......@@ -155,6 +155,9 @@
<ItemGroup>
<ClCompile Include="test.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\jlib\log2micros.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
......
......@@ -19,4 +19,9 @@
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\jlib\log2micros.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
#include "../../jlib/log2.h"
#include "../../jlib/net/resolve_fastest_ip.h"
int main(int argc, char** argv)
{
std::string domain = "baidu.com";
int ping_times = 4;
if (argc > 1) { domain = argv[1]; }
if (argc > 2) { ping_times = std::stoi(argv[2]); }
if (argc < 1) { printf("Usage: %s [domain] [ping times]\n", argv[0]); return 1; }
jlib::init_logger();
#ifndef _DEBUG
spdlog::get(jlib::g_logger_name)->set_level(spdlog::level::err);
#endif
std::string res;
int n = 0;
bool ret = jlib::net::get_domain_ip(domain, ping_times, res, [&n]() {
if (++n == 4) { n = 0; }
std::string msg = "waiting";
for (int i = 0; i < n; i++) { msg.push_back('.'); }
JLOG_INFO(msg);
});
if (ret) {
JLOG_INFO("get_domain_ip of [{}] ok: {}", domain, res);
printf("%s\n", res.data());
return 0;
} else {
JLOG_ERRO("get_domain_ip failed: {}", res);
printf("");
return 1;
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{65F9D4DA-BC6C-486D-8966-6ACCE077639D}</ProjectGuid>
<RootNamespace>testresolvefastestip</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(BOOST);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(BOOST)\stage\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(BOOST);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(BOOST)\stage\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="test_resolve_fastest_ip.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\jlib\net\resolve_fastest_ip.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="test_resolve_fastest_ip.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\jlib\net\resolve_fastest_ip.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment