Mon*_*RPG 17 c# wpf webrequest httpwebrequest network-traffic
我有以下功能来获取页面.我的问题是我想计算一下互联网连接的数量
入站(下载)和出站流量(已发送)
我怎样才能做到这一点 ?谢谢
我的功能
public static string func_fetch_Page(string srUrl, int irTimeOut = 60,
string srRequestUserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0",
string srProxy = null)
{
string srBody = "";
string srResult = "";
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(srUrl);
request.Timeout = irTimeOut * 1000;
request.UserAgent = srRequestUserAgent;
request.KeepAlive = true;
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
WebHeaderCollection myWebHeaderCollection = request.Headers;
myWebHeaderCollection.Add("Accept-Language", "en-gb,en;q=0.5");
myWebHeaderCollection.Add("Accept-Encoding", "gzip, deflate");
request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
using (WebResponse response = request.GetResponse())
{
using (Stream strumien = response.GetResponseStream())
{
using (StreamReader sr = new StreamReader(strumien))
{
srBody = sr.ReadToEnd();
srResult = "success";
}
}
}
}
catch ()
{
}
return srBody;
}
Run Code Online (Sandbox Code Playgroud)
C#.net 4.5 WPF应用程序
@Simon Mourier如何计算花费的流量
public static long long_GlobalDownload_KByte = 0;
public static long long_GlobalSent_KByte = 0;
Time _timer_fetch_download_upload = new Timer(getDownload_Upload_Values, null, 0, 100 * 1000);
public static void getDownload_Upload_Values(Object state)
{
using (Process p = Process.GetCurrentProcess())
{
foreach (var cnx in TcpConnection.GetAll().Where(c => c.ProcessId == p.Id))
{
Interlocked.Add(ref long_GlobalDownload_KByte, Convert.ToInt64(cnx.DataBytesIn));
Interlocked.Add(ref long_GlobalSent_KByte, Convert.ToInt64(cnx.DataBytesOut));
}
}
}
Run Code Online (Sandbox Code Playgroud)
一个Windows API可以给你这样的信息:GetPerTcpConnectionEStats IPv4连接和相关的IPV6 GetPerTcp6ConnectionEStats功能.请注意,您需要先使用SetPerTcpConnectionEStats才能获取任何统计信息,这通常需要管理员权限...
要获取所有连接的列表,可以使用GetExtendedTcpTable函数.它还可以为您提供连接的进程ID,这非常有用.
这些本机API并不容易使用,但我创建了一个包装所有这些的TcpConnection类.它可以在一个名为IPStats的小型WPF应用程序中找到:https://github.com/smourier/IPStats
因此,这里的困难是将.NET HttpWebRequest链接到连接列表中的TcpConnection.在连接存在之前,您无法获得任何统计信息,但是一旦创建了连接,就可以使用如下代码获取相应的连接:
static IEnumerable<TcpConnection> GetProcessConnection(IPEndPoint ep)
{
var p = Process.GetCurrentProcess();
return TcpConnection.GetAll().Where(c => ep.Equals(c.RemoteEndPoint) && c.ProcessId == p.Id);
}
HttpWebRequest req = ...
// this is how you can get the enpoint, or you can also built it by yourself manually
IPEndPoint remoteEndPoint;
req.ServicePoint.BindIPEndPointDelegate += (sp, rp, rc) =>
{
remoteEndPoint = rp;
return null;
};
// TODO: here, you need to connect, so the connection exists
var cnx = GetProcessConnection(remoteEndPoint).FirstOrDefault();
// access denied here means you don't have sufficient rights
cnx.DataStatsEnabled = true;
// TODO: here, you need to do another request, so the values are incremented
// now, you should get non-zero values here
// note TcpConnection also has int/out bandwidth usage, and in/out packet usage.
Console.WriteLine("DataBytesIn:" + cnx.DataBytesIn);
Console.WriteLine("DataBytesOut:" + cnx.DataBytesOut);
// if you need all connections in the current process, just do this
ulong totalBytesIn = 0;
ulong totalBytesOut = 0;
Process p = Process.GetCurrentProcess();
foreach (var cnx in TcpConnection.GetAll().Where(c => c.ProcessId == p.Id))
{
totalBytesIn += cnx.DataBytesIn;
totalBytesOut += cnx.DataBytesOut;
}
Run Code Online (Sandbox Code Playgroud)
有3个缺点:
更新:如果要连续监视给定进程的所有连接,我编写了一个ProcessTcpConnections实用程序类,它记住所有连接并总结它们的用法.它会像这样使用(在控制台应用程序示例中):
class Program
{
static void Main(string[] args)
{
ProcessTcpConnections p = new ProcessTcpConnections(Process.GetCurrentProcess().Id);
Timer timer = new Timer(UpdateStats, p, 0, 100);
do
{
// let's activate the network so we measure something...
using (WebClient client = new WebClient())
{
client.DownloadString("http://www.example.com");
}
Console.ReadKey(true); // press any key to download again
}
while (true);
}
private static void UpdateStats(object state)
{
ProcessTcpConnections p = (ProcessTcpConnections)state;
p.Update();
Console.WriteLine("DataBytesIn:" + p.DataBytesIn + " DataBytesOut:" + p.DataBytesOut);
}
}
public class ProcessTcpConnections : TcpConnectionGroup
{
public ProcessTcpConnections(int processId)
: base(c => c.ProcessId == processId)
{
ProcessId = processId;
}
public int ProcessId { get; private set; }
}
public class TcpConnectionGroup
{
private List<TcpConnectionStats> _states = new List<TcpConnectionStats>();
private Func<TcpConnection, bool> _groupFunc;
public TcpConnectionGroup(Func<TcpConnection, bool> groupFunc)
{
if (groupFunc == null)
throw new ArgumentNullException("groupFunc");
_groupFunc = groupFunc;
}
public void Update()
{
foreach (var conn in TcpConnection.GetAll().Where(_groupFunc))
{
if (!conn.DataStatsEnabled)
{
conn.DataStatsEnabled = true;
}
TcpConnectionStats existing = _states.Find(s => s.Equals(conn));
if (existing == null)
{
existing = new TcpConnectionStats();
_states.Add(existing);
}
existing.DataBytesIn = conn.DataBytesIn;
existing.DataBytesOut = conn.DataBytesOut;
existing.LocalEndPoint = conn.LocalEndPoint;
existing.RemoteEndPoint = conn.RemoteEndPoint;
existing.State = conn.State;
existing.LastUpdateTime = DateTime.Now;
}
}
public ulong DataBytesIn
{
get
{
ulong count = 0; foreach (var state in _states) count += state.DataBytesIn; return count;
}
}
public ulong DataBytesOut
{
get
{
ulong count = 0; foreach (var state in _states) count += state.DataBytesOut; return count;
}
}
private class TcpConnectionStats
{
public ulong DataBytesIn { get; set; }
public ulong DataBytesOut { get; set; }
public IPEndPoint LocalEndPoint { get; set; }
public IPEndPoint RemoteEndPoint { get; set; }
public TcpState State { get; set; }
public DateTime LastUpdateTime { get; set; }
public bool Equals(TcpConnection connection)
{
return LocalEndPoint.Equals(connection.LocalEndPoint) && RemoteEndPoint.Equals(connection.RemoteEndPoint);
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用FiddlerCore创建代理(只需要一个dll来引用)并将WebProxy设置为HttpWebRequest来计算发送和接收的字节数
public class WebConnectionStats
{
static int _Read = 0;
static int _Written = 0;
public static void Init(bool registerAsSystemProxy = false)
{
Fiddler.FiddlerApplication.OnReadRequestBuffer += (s, e) => Interlocked.Add(ref _Written, e.iCountOfBytes);
Fiddler.FiddlerApplication.OnReadResponseBuffer += (s, e) => Interlocked.Add(ref _Read, e.iCountOfBytes);
Fiddler.FiddlerApplication.Startup(8088, registerAsSystemProxy, true);
}
public static int Read
{
get { return _Read; }
}
public static int Written
{
get { return _Written; }
}
}
Run Code Online (Sandbox Code Playgroud)
WebConnectionStats.Init(); //call this only once
var client = HttpWebRequest.Create("http://stackoverflow.com") as HttpWebRequest;
client.Proxy = new WebProxy("127.0.0.1", 8088);
var resp = client.GetResponse();
var html = new StreamReader(resp.GetResponseStream()).ReadToEnd();
Console.WriteLine("Read: {0} Write: {1}", WebConnectionStats.Read,
WebConnectionStats.Written);
Run Code Online (Sandbox Code Playgroud)
PS1:此计数不包括Tcp标头的长度
归档时间: |
|
查看次数: |
1823 次 |
最近记录: |