C# 就近网络站点选择

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.IO;
  7 using System.Linq;
  8 using System.Net;
  9 using System.Text;
 10 using System.Threading;
 11 using System.Threading.Tasks;
 12 using System.Windows.Forms;
 13 using System.Text.RegularExpressions;
 14 using Util;
 15 
 16 namespace App
 17 {
 18     public partial class FormChooseSite : Form
 19     {
 20         private SynchronizationContext syncContext = null;
 21         private System.Windows.Forms.Timer autoEnterTimer = null;
 22 
 23         private RadioButton checkedRadioButton = null;
 24         private bool autoChoosedSite = false;
 25 
 26         private const string ServiceSitesConfigDate = "2016-7-18";
 27         private string serviceSitesXmlFile = null;
 28 
 29         public FormChooseSite()
 30         {
 31             InitializeComponent();
 32             syncContext = SynchronizationContext.Current;
 33             serviceSitesXmlFile = GetServiceSitesXmlFilePath();
 34 
 35             autoEnterTimer = new System.Windows.Forms.Timer();
 36             autoEnterTimer.Interval = 1000;
 37             autoEnterTimer.Tag = 3;
 38             autoEnterTimer.Tick += (s, e) =>
 39             {
 40                 int remainTimes = Convert.ToInt32(autoEnterTimer.Tag);
 41                 if (remainTimes == -1)
 42                 {
 43                     autoEnterTimer.Enabled = false;
 44                     return;
 45                 }
 46 
 47                 var choosedSite = checkedRadioButton.Tag as ServiceSite;
 48                 btnEnter.Text = string.Format("使用系统推荐的站点【{0}】进入系统 ({1})", choosedSite.SiteName, --remainTimes);
 49                 autoEnterTimer.Tag = remainTimes;
 50                 if (remainTimes <= 0)
 51                 {
 52                     autoEnterTimer.Enabled = false;
 53                     btnEnter.PerformClick();
 54                 }
 55             };
 56         }
 57 
 58 
 59 
 60         private void FrmChooseSite_Load(object sender, EventArgs e)
 61         {
 62             btnEnter.Enabled = false;
 63             layoutPanSites.Enabled = false;
 64             this.Cursor = Cursors.WaitCursor;
 65 
 66             Task.Factory.StartNew(() =>
 67             {
 68                 var serviceSiteList = GetServiceSiteList();
 69 
 70                 List<Task> taskList = new List<Task>();
 71                 string currentIp = null;
 72 
 73                 taskList.Add(Task.Factory.StartNew(() =>
 74                 {
 75                     currentIp = GetCurrentIpInfo();
 76                     syncContext.Post((o) => { labIpInfo.Text = currentIp; }, null);
 77                 }));
 78 
 79                 foreach (var item in serviceSiteList)
 80                 {
 81                     taskList.Add(Task.Factory.StartNew(() =>
 82                     {
 83                         item.TestAndLoadConnectionData(5, 2);
 84                         syncContext.Post(LoadServiceSiteInfo, item);
 85                     }));
 86                 }
 87 
 88                 Task.WaitAll(taskList.ToArray());
 89 
 90 
 91                 syncContext.Post((o) =>
 92                 {
 93                     //var sites = o as List<ServiceSite>;
 94                     //foreach (var item in serviceSiteList)
 95                     //{
 96                     //    LoadServiceSiteInfo(item);
 97                     //}
 98 
 99                     layoutPanSites.Controls.Remove(labLoading);
100                     btnEnter.Enabled = true;
101                     layoutPanSites.Enabled = true;
102                     this.Cursor = Cursors.Default;
103 
104                 }, serviceSiteList);
105 
106                 var bestServiceSite = GetBestServiceSite(serviceSiteList, currentIp);
107 
108                 syncContext.Post((o) =>
109                 {
110                     var site = o as ServiceSite;
111                     var rdbtn = layoutPanSites.Controls.Cast<Control>().FirstOrDefault(c => c.Tag.Equals(site)) as RadioButton;
112                     if (rdbtn != null)
113                     {
114                         autoChoosedSite = true;
115                         rdbtn.Checked = true;
116                         autoChoosedSite = false;
117                         this.Text += string.Format(" - [ 系统推荐站点:{0} ]", site.SiteName);
118 
119                         autoEnterTimer.Enabled = true;
120                     }
121                 }, bestServiceSite);
122 
123             });
124         }
125 
126         private string GetServiceSitesXmlFilePath()
127         {
128             if (!File.Exists(serviceSitesXmlFile))
129             {
130                 string xmlFile = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Bin\\";
131                 if (!Directory.Exists(xmlFile))
132                 {
133                     Directory.CreateDirectory(xmlFile);
134                 }
135                 serviceSitesXmlFile = xmlFile + "ServiceSites.xml";
136             }
137             return serviceSitesXmlFile;
138         }
139 
140         private void LoadServiceSiteInfo(object state)
141         {
142             var serviceSite = state as ServiceSite;
143             var rdBtn = new MyStyleRedioButton();
144             rdBtn.Name = "rdBtn" + layoutPanSites.Controls.Count.ToString();
145             rdBtn.Tag = serviceSite;
146             rdBtn.Text = string.Format("{0}:{1}(平均耗时:{2}ms;丢包率:{3})", serviceSite.SiteName, serviceSite.ConnectionStatus ? GetEnumDescription(serviceSite.ConnectionSpeed) : "失败", serviceSite.AvgSpeed, serviceSite.PacketLossRate);
147             rdBtn.AutoSize = false;
148             rdBtn.TextAlign = ContentAlignment.MiddleLeft;
149             rdBtn.Width = 280;
150             rdBtn.Height = 30;
151             rdBtn.Padding = new System.Windows.Forms.Padding() { Left = 5 };
152             rdBtn.Margin = new System.Windows.Forms.Padding(3, 5, 3, 5);
153             //rdBtn.BackGroundColor = Color.Purple; //ColorTranslator.FromHtml("#9F79EE");
154             rdBtn.ForeColor = Color.White;
155             if (serviceSite.ConnectionStatus)
156             {
157                 if (serviceSite.ConnectionSpeed >= ServiceSite.ConnectionSpeeds.Normal)
158                 {
159                     rdBtn.BackGroundColor = Color.Purple;
160                 }
161                 else
162                 {
163                     rdBtn.BackGroundColor = Color.Orange;
164                 }
165             }
166             else
167             {
168                 rdBtn.BackGroundColor = Color.Red;
169             }
170             rdBtn.CheckedChanged += rdBtn_CheckedChanged;
171             layoutPanSites.Controls.Add(rdBtn);
172             layoutPanSites.Controls.SetChildIndex(rdBtn, layoutPanSites.Controls.Count - 2);
173         }
174 
175         private void rdBtn_CheckedChanged(object sender, EventArgs e)
176         {
177             var rdBtn = sender as RadioButton;
178             if (rdBtn.Checked)
179             {
180                 var choosedSite = rdBtn.Tag as ServiceSite;
181                 checkedRadioButton = rdBtn;
182                 if (autoChoosedSite)
183                 {
184                     btnEnter.Text = string.Format("使用系统推荐的站点【{0}】进入系统 (3)", choosedSite.SiteName);
185                 }
186                 else
187                 {
188                     btnEnter.Text = string.Format("使用当前选择的站点【{0}】进入系统", choosedSite.SiteName);
189                     autoEnterTimer.Tag = -1;
190                 }
191             }
192         }
193 
194         private string GetEnumDescription(Enum enumValue)
195         {
196             string str = enumValue.ToString();
197             System.Reflection.FieldInfo field = enumValue.GetType().GetField(str);
198             object[] objs = field.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), false);
199             if (objs == null || objs.Length == 0) return str;
200             System.ComponentModel.DescriptionAttribute da = (System.ComponentModel.DescriptionAttribute)objs[0];
201             return da.Description;
202         }
203 
204         private List<ServiceSite> GetServiceSiteList()
205         {
206 
207         InitializeConfigInfo:
208 
209             if (!File.Exists(serviceSitesXmlFile))
210             {
211                 SaveServiceSiteList();
212             }
213 
214             DataSet serviceSiteDs = new DataSet();
215             serviceSiteDs.ReadXml(serviceSitesXmlFile);
216 
217             string serviceSitesConfigDateFromXml = (serviceSiteDs.ExtendedProperties["ConfigDate"] ?? "").ToString();
218 
219             if (!serviceSitesConfigDateFromXml.Equals(ServiceSitesConfigDate, StringComparison.OrdinalIgnoreCase))//配置日期不相同,则需重新生成
220             {
221                 File.Delete(serviceSitesXmlFile);
222                 goto InitializeConfigInfo;
223             }
224 
225             List<ServiceSite> serviceSiteList = new List<ServiceSite>();
226             if (serviceSiteDs.Tables.Contains("ServiceSite"))
227             {
228                 foreach (DataRow row in serviceSiteDs.Tables["ServiceSite"].Rows)
229                 {
230                     serviceSiteList.Add(new ServiceSite(row["SiteName"].ToString(), row["IpAddress"].ToString(), Convert.ToInt32(row["Port"]),
231                                         row["Region"].ToString(), row["NetProvider"].ToString()));
232                 }
233             }
234             return serviceSiteList;
235         }
236 
237         private void SaveServiceSiteList()
238         {
239 
240             DataSet serviceSiteDs = new DataSet("ServiceSiteConfig");
241             serviceSiteDs.ExtendedProperties.Add("ConfigDate", ServiceSitesConfigDate);
242 
243             DataTable dt = new DataTable("ServiceSite");
244             dt.Columns.Add("SiteName", typeof(string));
245             dt.Columns.Add("IpAddress", typeof(string));
246             dt.Columns.Add("Port", typeof(int));
247             dt.Columns.Add("Region", typeof(string));
248             dt.Columns.Add("NetProvider", typeof(string));
249 
250             serviceSiteDs.Tables.Add(dt);
251 
252             dt.Rows.Add("深圳电信1", "xxx.xxx.xxx.xxx", 8080, "深圳", "电信");
253             dt.Rows.Add("深圳电信2", "xxx.xxx.xxx.xxx", 8080, "深圳", "电信");
254             dt.Rows.Add("深圳多网", "xxx.xxx.xxx.xxx", 8080, "深圳", "多网");
255             dt.Rows.Add("深圳联通", "xxx.xxx.xxx.xxx", 8080, "深圳", "联通");258 
259             serviceSiteDs.WriteXml(serviceSitesXmlFile, XmlWriteMode.WriteSchema);
260         }
261 
262         private string GetCurrentIpInfo()
263         {
264             using (WebClient client = new WebClient())
265             {
266                 string url = "http://1212.ip138.com/ic.asp";
267                 string content = client.DownloadString(url);
268                 Regex rg = new Regex("(?<=<center>).+(?=</center>)", RegexOptions.IgnoreCase);
269                 return rg.Match(content).Value;
270             }
271         }
272 
273         private ServiceSite GetBestServiceSite(List<ServiceSite> siteList, string currentIp)
274         {
275             var okSites = siteList.Where(s => s.ConnectionStatus);//获取端口连接正常的站点列表
276 
277             //var sameNetProviderSites = okSites.Where(s => currentIp.IndexOf(s.NetProvider, StringComparison.OrdinalIgnoreCase) >= 0);//获取同属一个网络运营商的站点列表
278             //if (sameNetProviderSites == null || sameNetProviderSites.Count() <= 0)
279             //{
280             //    sameNetProviderSites = okSites;
281             //}
282 
283             //var sameRegionSites = sameNetProviderSites.Where(s => currentIp.IndexOf(s.Region, StringComparison.OrdinalIgnoreCase) >= 0);//获取同属于一个城市(地区)的站点列表
284             //if (sameRegionSites == null || sameRegionSites.Count() <= 0)
285             //{
286             //    sameRegionSites = sameNetProviderSites;
287             //}
288 
289             return okSites.OrderBy(s => s.AvgSpeed).FirstOrDefault();//返回平均速度最高的一个站点作为最佳站点
290         }
291 
292 
293         private void SiteSetting()
294         {
295             var choosedSite = checkedRadioButton.Tag as ServiceSite;
296             //Program.AppWebSrvHost = string.Format("{0}:{1}", choosedSite.IpAddress, choosedSite.Port);
297         }
298 
299         private void btnEnter_Click(object sender, EventArgs e)
300         {
301             SiteSetting();
302             this.DialogResult = DialogResult.OK;
303         }
304     }
305 }

闲着就高了这个玩意,大家可以看看,这个是根据本地IP测试连接其他站点,选择最优站点的一段代码,WEB端我不会写HTML就没搞,不过后端都差不多,可以写成接口的方式调用。

转载于:https://www.cnblogs.com/zhangkan/p/5681749.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值