using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace Rainbow.Services;
/// <summary>Windows 网络流量统计提供者。通过 Get-NetAdapterStatistics PowerShell 采集</summary>
public class WindowsNetworkStatProvider : INetworkStatProvider
{
/// <summary>获取所有网口的流量统计数据</summary>
public async Task<List<InterfaceStatData>> GetInterfaceStatsAsync()
{
var result = new List<InterfaceStatData>();
try
{
// PowerShell Get-NetAdapterStatistics 获取网口统计
var psi = new ProcessStartInfo("powershell",
"-Command \"Get-NetAdapterStatistics | Select-Object Name, ReceivedBytes, SentBytes, ReceivedPackets, SentPackets, ReceivedErrors, SentErrors | ConvertTo-Json\"")
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
};
using var proc = Process.Start(psi);
if (proc == null) return result;
var output = await proc.StandardOutput.ReadToEndAsync();
await proc.WaitForExitAsync().WaitAsync(TimeSpan.FromSeconds(15));
if (String.IsNullOrEmpty(output)) return result;
// 简单 JSON 解析(不依赖 Newtonsoft.Json)
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
// 处理单个对象或数组
var items = output.TrimStart();
if (items.StartsWith("["))
{
// JSON 数组
var depth = 0;
var start = 0;
for (var i = 0; i < items.Length; i++)
{
if (items[i] == '{')
{
if (depth == 0) start = i;
depth++;
}
else if (items[i] == '}')
{
depth--;
if (depth == 0 && start < i)
{
var obj = items.Substring(start, i - start + 1);
var stat = ParseStatObject(obj, timestamp);
if (stat != null) result.Add(stat);
start = i + 1;
}
}
}
}
else if (items.StartsWith("{"))
{
var stat = ParseStatObject(items, timestamp);
if (stat != null) result.Add(stat);
}
}
catch
{
// 异常时返回空列表
}
return result;
}
/// <summary>获取当前系统总连接数</summary>
public Int32 GetConnectionCount()
{
try
{
var psi = new ProcessStartInfo("netstat", "-an")
{
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
};
using var proc = Process.Start(psi);
if (proc == null) return 0;
var output = proc.StandardOutput.ReadToEnd();
proc.WaitForExit(5000);
var count = 0;
foreach (var line in output.Split('\n'))
{
if (line.Trim().Contains("ESTABLISHED"))
count++;
}
return count;
}
catch
{
return 0;
}
}
/// <summary>从 PowerShell JSON 对象中解析网口统计数据</summary>
private static InterfaceStatData? ParseStatObject(String json, Int64 timestamp)
{
try
{
var name = ExtractJsonValue(json, "Name") ?? "";
var rxBytes = ParseLong(ExtractJsonValue(json, "ReceivedBytes"));
var txBytes = ParseLong(ExtractJsonValue(json, "SentBytes"));
var rxPackets = ParseLong(ExtractJsonValue(json, "ReceivedPackets"));
var txPackets = ParseLong(ExtractJsonValue(json, "SentPackets"));
var rxErrors = ParseLong(ExtractJsonValue(json, "ReceivedErrors"));
var txErrors = ParseLong(ExtractJsonValue(json, "SentErrors"));
if (String.IsNullOrEmpty(name)) return null;
return new InterfaceStatData
{
Name = name,
RxBytes = rxBytes,
TxBytes = txBytes,
RxPackets = rxPackets,
TxPackets = txPackets,
RxErrors = rxErrors,
TxErrors = txErrors,
Timestamp = timestamp,
};
}
catch
{
return null;
}
}
/// <summary>从简化的 JSON 中提取字段值(无 Newtonsoft.Json 依赖)</summary>
private static String? ExtractJsonValue(String json, String key)
{
var search = $"\"{key}\":";
var idx = json.IndexOf(search, StringComparison.OrdinalIgnoreCase);
if (idx < 0) return null;
var start = idx + search.Length;
// 跳过空白
while (start < json.Length && json[start] == ' ') start++;
if (start >= json.Length) return null;
if (json[start] == '"')
{
// 字符串值
start++;
var end = json.IndexOf('"', start);
return end > start ? json.Substring(start, end - start) : null;
}
else
{
// 数值或 null
var end = start;
while (end < json.Length && json[end] != ',' && json[end] != '}' && json[end] != '\n' && json[end] != '\r')
end++;
var val = json.Substring(start, end - start).Trim();
return val == "null" ? null : val;
}
}
private static Int64 ParseLong(String? value)
{
if (String.IsNullOrEmpty(value)) return 0;
return Int64.TryParse(value, out var result) ? result : 0;
}
}
|