如果检测因特网连接正忙

我们正在开发将安装在PC上的应用程序,它会从我们的服务器进行一些后台上传和下载/。 其中一个要求是检测是否Internet连接目前正忙(上面说的50%的利用率),如果是,它需要回退,并尝试另一次。 最主要的原因是为了确保应用程序,如果他们在游戏的中间不带用户体验的干扰,看在线电影或积极下载文件

经过一番思考和研究谷歌和SO当然,我仍然没有找到关于如何实现一个很好的方式,所以决定在这里丢了这一点。 该应用程序是用C#实现,.NET 4.0和我要找各种形式的回应-关于如何实现在C#或其他语言,伪逻辑或方法的任何一种实现-本地PC具有良好的精度足以在互联网流量利用率测量。

为了避免重复工作,到目前为止,我还尝试了这些(以及为什么它们不适合)

  • 使用WMI获得网络统计。 最让帖子和解决方案在那里,因为指以此为方法,但它不符合我们的要求是发送的字节测量赞成/反对的利用将产生的LAN流量很好地衡量网络接口的容量(例如1GB以太网卡)接受但不适用于互联网流量(其中实际的互联网带宽可能只说8Mbps的)
  • .NET网络信息统计或性能计数器的用途 - 产生类似的读数以上,因此具有相同的缺点
  • 使用ICMP(平),测量RTT。 有人建议400ms的RTT被认为是繁忙的网络缓慢和很好的迹象,但有人告诉我,带调制解调器的用户(是的,我们必须支持),使用反向代理或微波链路经常得到平上面,因此不是一个好的测量
  • 开始下载一个已知的文件测量速度 - 这本身就产生我们正试图避免交通,也如果检查是往往不够,我们的应用程序将最终造就了很多上网流量 - 而这又不是很理想
  • MOD:使用BITS - 该服务可以在用户的​​电脑禁用,需要组策略的变化,并假设服务器是IIS(自定义配置)和我们的情况下,我们的服务器不是IIS

所以这里,我完全混淆视听,寻找一些建议。 我突出问题文本,这样你们就不会迷路读这篇文章,不知道问题是什么。 谢谢。

--------------解决方案-------------

可以使用UPnP查询路由器,和retrive发送和接收通过网络的字节数。 可以继续检查在路由器上该值来确定该活动是什么。 不幸的是这个功能似乎并没有被充分证明,但它是可以实现一个C#应用程序中的UPnP通信功能。 您将需要使用UDP查询路由器(UPnP的发现),一旦你找到了设备,查询其功能,然后查询发送的数据包的数量和使用Web客户端(TCP)Internet网关设备接收。

代码在UPnP库:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Xml;
using System.IO;
namespace UPNPLib
{
public class RouterElement
{
public RouterElement()
{
}
public override string ToString()
{
return Name;
}
public List children = new List();
public RouterElement parent;
public string Name;
public string Value;
public RouterElement this[string name] {
get
{
foreach (RouterElement et in children)
{
if (et.Name.ToLower().Contains(name.ToLower()))
{
return et;
}
}
foreach (RouterElement et in children)
{
Console.WriteLine(et.Name);
}
throw new KeyNotFoundException("Unable to find the specified entry");
}
}
public RouterElement(XmlNode node, RouterElement _parent)
{

Name = node.Name;
if (node.ChildNodes.Count
/// Gets the root URL of the device
///
///
public static string GetRootUrl()
{
StringBuilder mbuilder = new StringBuilder();
mbuilder.Append("M-SEARCH * HTTP/1.1\r\n");
mbuilder.Append("HOST: 239.255.255.250:1900\r\n");
mbuilder.Append("ST:upnp:rootdevice\r\n");
mbuilder.Append("MAN:\"ssdp:discover\"\r\n");
mbuilder.Append("MX:3\r\n\r\n");
UdpClient mclient = new UdpClient();
byte[] dgram = Encoding.ASCII.GetBytes(mbuilder.ToString());
mclient.Send(dgram,dgram.Length,new IPEndPoint(IPAddress.Broadcast,1900));
IPEndPoint mpoint = new IPEndPoint(IPAddress.Any, 0);
rootsearch:

dgram = mclient.Receive(ref mpoint);
string mret = Encoding.ASCII.GetString(dgram);
string orig = mret;
mret = mret.ToLower();
string url = orig.Substring(mret.IndexOf("location:") + "location:".Length, mret.IndexOf("\r", mret.IndexOf("location:")) - (mret.IndexOf("location:") + "location:".Length));
WebClient wclient = new WebClient();
try
{
Console.WriteLine("POLL:" + url);
string reply = wclient.DownloadString(url);

if (!reply.ToLower().Contains("router"))
{
goto rootsearch;
}
}
catch (Exception)
{
goto rootsearch;
}
return url;
}
public static RouterElement enumRouterFunctions(string url)
{

XmlReader mreader = XmlReader.Create(url);
XmlDocument md = new XmlDocument();
md.Load(mreader);
XmlNodeList rootnodes = md.GetElementsByTagName("serviceList");
RouterElement elem = new RouterElement();
foreach (XmlNode et in rootnodes)
{
RouterElement el = new RouterElement(et, null);
elem.children.Add(el);
}

return elem;
}
public static RouterElement getRouterInformation(string url)
{
XmlReader mreader = XmlReader.Create(url);
XmlDocument md = new XmlDocument();
md.Load(mreader);
XmlNodeList rootnodes = md.GetElementsByTagName("device");
return new RouterElement(rootnodes[0], null);
}

}
public class RouterMethod
{
string url;
public string MethodName;
string parentname;
string MakeRequest(string URL, byte[] data, string[] headers)
{
Uri mri = new Uri(URL);
TcpClient mclient = new TcpClient();
mclient.Connect(mri.Host, mri.Port);
Stream mstream = mclient.GetStream();
StreamWriter textwriter = new StreamWriter(mstream);
textwriter.Write("POST "+mri.PathAndQuery+" HTTP/1.1\r\n");

textwriter.Write("Connection: Close\r\n");

textwriter.Write("Content-Type: text/xml; charset=\"utf-8\"\r\n");

foreach (string et in headers)
{
textwriter.Write(et + "\r\n");
}
textwriter.Write("Content-Length: " + (data.Length).ToString()+"\r\n");
textwriter.Write("Host: " + mri.Host+":"+mri.Port+"\r\n");

textwriter.Write("\r\n");
textwriter.Flush();

Stream reqstream = mstream;
reqstream.Write(data, 0, data.Length);
reqstream.Flush();
StreamReader reader = new StreamReader(mstream);
while (reader.ReadLine().Length > 2)
{

}
return reader.ReadToEnd();
}
public RouterElement Invoke(string[] args)
{

MemoryStream mstream = new MemoryStream();
StreamWriter mwriter = new StreamWriter(mstream);
//TODO: Implement argument list
string arglist = "";

mwriter.Write("" + "" + "");

mwriter.Write("");//" + arglist + "");
mwriter.Write("");
mwriter.Flush();

List headers = new List();

headers.Add("SOAPAction: \"" + parentschema + "#" + MethodName + "\"");

mstream.Position = 0;
byte[] dgram = new byte[mstream.Length];

mstream.Read(dgram, 0, dgram.Length);

XmlDocument mdoc = new XmlDocument();
string txt = MakeRequest(url, dgram, headers.ToArray());
mdoc.LoadXml(txt);
try
{
RouterElement elem = new RouterElement(mdoc.ChildNodes[0], null);

return elem["Body"].children[0];
}
catch (Exception er)
{
RouterElement elem = new RouterElement(mdoc.ChildNodes[1], null);
return elem["Body"].children[0];
}

}
public List parameters = new List();
string baseurl;
string parentschema;
public RouterMethod(string svcurl, RouterElement element,string pname, string baseURL, string svcpdsc)
{
parentschema = svcpdsc;
baseurl = baseURL;
parentname = pname;
url = svcurl;
MethodName = element["name"].Value;
try
{
foreach (RouterElement et in element["argumentList"].children)
{
parameters.Add(et.children[0].Value);
}
}
catch (KeyNotFoundException)
{
}
}
}
public class RouterService
{
string url;
public string ServiceName;
public List methods = new List();
public RouterMethod GetMethodByNonCaseSensitiveName(string name)
{
foreach (RouterMethod et in methods)
{
if (et.MethodName.ToLower() == name.ToLower())
{
return et;
}
}
throw new KeyNotFoundException();
}
public RouterService(RouterElement element, string baseurl)
{

ServiceName = element["serviceId"].Value;
url = element["controlURL"].Value;

WebClient mclient = new WebClient();
string turtle = element["SCPDURL"].Value;
if (!turtle.ToLower().Contains("http"))
{
turtle = baseurl + turtle;
}
Console.WriteLine("service URL " + turtle);
string axml = mclient.DownloadString(turtle);
XmlDocument mdoc = new XmlDocument();
if (!url.ToLower().Contains("http"))
{
url = baseurl + url;
}
mdoc.LoadXml(axml);
XmlNode mainnode = mdoc.GetElementsByTagName("actionList")[0];
RouterElement actions = new RouterElement(mainnode, null);
foreach (RouterElement et in actions.children)
{
RouterMethod method = new RouterMethod(url, et,ServiceName,baseurl,element["serviceType"].Value);
methods.Add(method);
}

}
}
}


Code for a bandwidth meter:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using UPNPLib;
using System.IO;

namespace bandwidthmeter
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
BinaryReader mreader = new BinaryReader(File.Open("bandwidthlog.txt", FileMode.OpenOrCreate));
if (mreader.BaseStream.Length > 0)
{
prevsent = mreader.ReadInt64();
prevrecv = mreader.ReadInt64();
}
mreader.Close();
List services = new List();
string fullurl = UPNP.GetRootUrl();
RouterElement router = UPNP.enumRouterFunctions(fullurl);
Console.WriteLine("Router feature enumeration complete");
foreach (RouterElement et in router.children)
{

services.Add(new RouterService(et.children[0], fullurl.Substring(0, fullurl.IndexOf("/", "http://".Length+1))));
}
getReceiveDelegate = services[1].GetMethodByNonCaseSensitiveName("GetTotalBytesReceived");
getSentDelegate = services[1].GetMethodByNonCaseSensitiveName("GetTotalBytesSent");
Console.WriteLine("Invoking " + getReceiveDelegate.MethodName);
//Console.WriteLine(services[1].GetMethodByNonCaseSensitiveName("GetTotalPacketsSent").Invoke(null));

Timer mymer = new Timer();
mymer.Tick += new EventHandler(mymer_Tick);
mymer.Interval = 1000;
mymer.Start();
FormClosed += new FormClosedEventHandler(Form1_FormClosed);
}
long prevsent = 0;
long prevrecv = 0;
void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
BinaryWriter mwriter = new BinaryWriter(File.Open("bandwidthlog.txt", FileMode.OpenOrCreate));
mwriter.Write(getsent());
mwriter.Write(getreceived());
mwriter.Flush();
mwriter.Close();

}
long getsent()
{
long retval = Convert.ToInt64(getSentDelegate.Invoke(null).children[0].Value);
if (prevsent > retval)
{
retval = prevsent + retval;
}
return retval;
}
long getreceived()
{
long retval = Convert.ToInt64(getReceiveDelegate.Invoke(null).children[0].Value);
if (prevrecv > retval)
{
retval = prevrecv + retval;
}
return retval;
}
void mymer_Tick(object sender, EventArgs e)
{
label1.Text = "Sent: "+(getsent()/1024/1024).ToString()+"MB\nReceived: "+(getreceived()/1024/1024).ToString()+"MB";

}
RouterMethod getSentDelegate;
RouterMethod getReceiveDelegate;

}
}

你有没有使用后台智能传输服务(BITS)考虑。 它的设计已经做好这项工作:

后台智能传输服务(BITS)传输文件在客户端和服务器之间(下载或上载),并提供与转让进展情况的信息。 您也可以从对等下载文件。

和,

保留的其他网络应用程序的响应。

我不知道,如果有一个管理界面,它(我可以看到参考PowerShell命令),所以你可能需要使用COM互操作来使用它。

使您打靶假设Windows PC上的(如你所说,你在C#中开发),你看着BITS,后台智能传输服务?

还有如何使用C#MSDN上挂接到这样的例子和其他地方,如http://msdn.microsoft.com/en-us/magazine/cc188766.aspx

分类:C# 时间:2015-03-15 人气:0
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.884 (s). 10 q(s)