开源 企业版 高校版 私有云 模力方舟 AI 队友
代码拉取完成,页面将自动刷新
加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
已有帐号? 立即登录
文件
master
分支 (2)
标签 (45)
master
v1.x
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.9
2.0.8
2.0.7
2.0.6
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
2.0.0-beta3
2.0.0-beta2
2.0.0-beta1
1.2.0
1.1.9
master
分支 (2)
标签 (45)
master
v1.x
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.9
2.0.8
2.0.7
2.0.6
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
2.0.0-beta3
2.0.0-beta2
2.0.0-beta1
1.2.0
1.1.9
克隆/下载
克隆/下载
提示
下载代码请复制以下命令到终端执行
为确保你提交的代码身份被 Gitee 正确识别,请执行以下命令完成配置
初次使用 SSH 协议进行代码克隆、推送等操作时,需按下述提示完成 SSH 配置
1 生成 RSA 密钥
2 获取 RSA 公钥内容,并配置到 SSH公钥
在 Gitee 上使用 SVN,请访问 使用指南
使用 HTTPS 协议时,命令行会出现如下账号密码验证步骤。基于安全考虑,Gitee 建议 配置并使用私人令牌 替代登录密码进行克隆、推送等操作
Username for 'https://gitee.com': userName
Password for 'https://userName@gitee.com': # 私人令牌
master
分支 (2)
标签 (45)
master
v1.x
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.9
2.0.8
2.0.7
2.0.6
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
2.0.0-beta3
2.0.0-beta2
2.0.0-beta1
1.2.0
1.1.9
FastGithub
/
FastGithub.DomainResolve
/
IPAddressService.cs
FastGithub
/
FastGithub.DomainResolve
/
IPAddressService.cs
IPAddressService.cs 5.54 KB
一键复制 编辑 原始数据 按行查看 历史
jiulang 提交于 2021年11月26日 22:21 +08:00 . network异常
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
namespace FastGithub.DomainResolve
{
/// <summary>
/// IP服务
/// 域名IP关系缓存10分钟
/// IPEndPoint时延缓存5分钟
/// IPEndPoint连接超时5秒
/// </summary>
sealed class IPAddressService
{
private record DomainAddress(string Domain, IPAddress Address);
private readonly TimeSpan domainAddressExpiration = TimeSpan.FromMinutes(10d);
private readonly IMemoryCache domainAddressCache = new MemoryCache(Options.Create(new MemoryCacheOptions()));
private record AddressElapsed(IPAddress Address, TimeSpan Elapsed);
private readonly TimeSpan problemElapsedExpiration = TimeSpan.FromMinutes(1d);
private readonly TimeSpan normalElapsedExpiration = TimeSpan.FromMinutes(5d);
private readonly TimeSpan connectTimeout = TimeSpan.FromSeconds(5d);
private readonly IMemoryCache addressElapsedCache = new MemoryCache(Options.Create(new MemoryCacheOptions()));
private readonly DnsClient dnsClient;
/// <summary>
/// IP服务
/// </summary>
/// <param name="dnsClient"></param>
public IPAddressService(DnsClient dnsClient)
{
this.dnsClient = dnsClient;
}
/// <summary>
/// 并行获取可连接的IP
/// </summary>
/// <param name="dnsEndPoint"></param>
/// <param name="oldAddresses"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IPAddress[]> GetAddressesAsync(DnsEndPoint dnsEndPoint, IEnumerable<IPAddress> oldAddresses, CancellationToken cancellationToken)
{
var ipEndPoints = new HashSet<IPEndPoint>();
// 历史未过期的IP节点
foreach (var address in oldAddresses)
{
var domainAddress = new DomainAddress(dnsEndPoint.Host, address);
if (this.domainAddressCache.TryGetValue(domainAddress, out _))
{
ipEndPoints.Add(new IPEndPoint(address, dnsEndPoint.Port));
}
}
// 新解析出的IP节点
await foreach (var address in this.dnsClient.ResolveAsync(dnsEndPoint, fastSort: false, cancellationToken))
{
ipEndPoints.Add(new IPEndPoint(address, dnsEndPoint.Port));
var domainAddress = new DomainAddress(dnsEndPoint.Host, address);
this.domainAddressCache.Set(domainAddress, default(object), this.domainAddressExpiration);
}
if (ipEndPoints.Count == 0)
{
return Array.Empty<IPAddress>();
}
var addressElapsedTasks = ipEndPoints.Select(item => this.GetAddressElapsedAsync(item, cancellationToken));
var addressElapseds = await Task.WhenAll(addressElapsedTasks);
return addressElapseds
.Where(item => item.Elapsed < TimeSpan.MaxValue)
.OrderBy(item => item.Elapsed)
.Select(item => item.Address)
.ToArray();
}
/// <summary>
/// 获取IP节点的时延
/// </summary>
/// <param name="endPoint"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task<AddressElapsed> GetAddressElapsedAsync(IPEndPoint endPoint, CancellationToken cancellationToken)
{
if (this.addressElapsedCache.TryGetValue<AddressElapsed>(endPoint, out var addressElapsed))
{
return addressElapsed;
}
var stopWatch = Stopwatch.StartNew();
try
{
using var timeoutTokenSource = new CancellationTokenSource(this.connectTimeout);
using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutTokenSource.Token);
using var socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
await socket.ConnectAsync(endPoint, linkedTokenSource.Token);
addressElapsed = new AddressElapsed(endPoint.Address, stopWatch.Elapsed);
return this.addressElapsedCache.Set(endPoint, addressElapsed, this.normalElapsedExpiration);
}
catch (Exception ex)
{
cancellationToken.ThrowIfCancellationRequested();
addressElapsed = new AddressElapsed(endPoint.Address, TimeSpan.MaxValue);
var expiration = IsLocalNetworkProblem(ex) ? this.problemElapsedExpiration : this.normalElapsedExpiration;
return this.addressElapsedCache.Set(endPoint, addressElapsed, expiration);
}
finally
{
stopWatch.Stop();
}
}
/// <summary>
/// 是否为本机网络问题
/// </summary>
/// <param name="ex"></param>
/// <returns></returns>
private static bool IsLocalNetworkProblem(Exception ex)
{
if (ex is not SocketException socketException)
{
return false;
}
var code = socketException.SocketErrorCode;
return code == SocketError.NetworkDown || code == SocketError.NetworkUnreachable;
}
}
}
Loading...
举报
举报成功
我们将于2个工作日内通过站内信反馈结果给你!
请认真填写举报原因,尽可能描述详细。
请选择举报类型
取消
发送
误判申诉

此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。

如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。

取消
提交

简介

FastGithub mirror
暂无标签
MIT
使用 MIT 开源许可协议
取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
编辑仓库简介
简介内容
主页
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/einstein666/FastGithub.git
git@gitee.com:einstein666/FastGithub.git
einstein666
FastGithub
FastGithub
master
点此查找更多帮助

搜索帮助

评论
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册

AltStyle によって変換されたページ (->オリジナル) /