gpt4 book ai didi

c# - 如何计算 HttpWebRequest 花费的出站和入站互联网流量

转载 作者:可可西里 更新时间:2023-11-01 03:00:11 28 4
gpt4 key购买 nike

我有以下函数来获取页面。我的问题是我想计算花费了多少互联网连接

入站(下载)和出站流量(发送)

我该怎么做?谢谢

我的函数

 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;
}

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));
}
}
}

最佳答案

一个 Windows API 可以为您提供以下信息:GetPerTcpConnectionEStats用于 IPV4 连接和关联的 IPV6 GetPerTcp6ConnectionEStats 函数。注意你需要使用 SetPerTcpConnectionEStats在能够获得任何统计数据之前,通常需要管理员权限...

要获取所有连接的列表,您可以使用 GetExtendedTcpTable功能。它还可以为您提供连接的进程 ID,这非常有用。

这些是 native 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;
}

有3个缺点:

  • 您需要成为管理员才能启用数据统计;
  • 您无法获得第一个请求的统计信息。这可能不是问题,具体取决于您的上下文;
  • HttpWebRequest 的连接和 TCP 连接之间的匹配可能更难确定,因为您可以有多个到远程端点的连接,即使在同一个进程中也是如此。区分的唯一方法是确定本地端点(尤其是端口)并使用此本地端点扩展 GetProcessConnection。不幸的是,没有简单的方法可以做到这一点。这是一个相关的答案:How do I get the local port number of an HttpWebRequest?

更新:如果您想持续监控给定进程的所有连接,我编写了一个 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);
}
}
}

关于c# - 如何计算 HttpWebRequest 花费的出站和入站互联网流量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25296153/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com