69 lines
2.2 KiB
C#
69 lines
2.2 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace FastGithub.DomainResolve
|
|
{
|
|
/// <summary>
|
|
/// IP延时
|
|
/// </summary>
|
|
[DebuggerDisplay("Adddress={Adddress} Elapsed={Elapsed}")]
|
|
struct IPAddressElapsed
|
|
{
|
|
private static readonly TimeSpan maxConnectTimeout = TimeSpan.FromSeconds(5d);
|
|
|
|
/// <summary>
|
|
/// 获取IP地址
|
|
/// </summary>
|
|
public IPAddress Adddress { get; }
|
|
|
|
/// <summary>
|
|
/// 获取延时
|
|
/// </summary>
|
|
public TimeSpan Elapsed { get; }
|
|
|
|
/// <summary>
|
|
/// IP延时
|
|
/// </summary>
|
|
/// <param name="adddress"></param>
|
|
/// <param name="elapsed"></param>
|
|
public IPAddressElapsed(IPAddress adddress, TimeSpan elapsed)
|
|
{
|
|
this.Adddress = adddress;
|
|
this.Elapsed = elapsed;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取连接耗时
|
|
/// </summary>
|
|
/// <param name="address"></param>
|
|
/// <param name="port"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public static async Task<IPAddressElapsed> ParseAsync(IPAddress address, int port, CancellationToken cancellationToken)
|
|
{
|
|
var stopWatch = Stopwatch.StartNew();
|
|
try
|
|
{
|
|
using var timeoutTokenSource = new CancellationTokenSource(maxConnectTimeout);
|
|
using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutTokenSource.Token);
|
|
using var socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
|
await socket.ConnectAsync(address, port, linkedTokenSource.Token);
|
|
return new IPAddressElapsed(address, stopWatch.Elapsed);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|
return new IPAddressElapsed(address, TimeSpan.MaxValue);
|
|
}
|
|
finally
|
|
{
|
|
stopWatch.Stop();
|
|
}
|
|
}
|
|
}
|
|
}
|