U:处理网速可能为负数的问题
This commit is contained in:
1 parent
095783ea61
commit
7d1d3d9220
4 files changed
+261
-17
No files matched your search
@@ -141,6 +141,35 @@ public class ConnectionInfo
|
||||
public long LastBytesSent { get; set; }
|
||||
public long LastBytesReceived { get; set; }
|
||||
public DateTime LastSpeedCalculationTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 重置次数统计
|
||||
/// </summary>
|
||||
public int ResetCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 累积发送总量(跨重置)
|
||||
/// </summary>
|
||||
public long TotalBytesSentAccumulated { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 累积接收总量(跨重置)
|
||||
/// </summary>
|
||||
public long TotalBytesReceivedAccumulated { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连接类型(持久/临时)
|
||||
/// </summary>
|
||||
public ConnectionType ConnectionType { get; set; }
|
||||
}
|
||||
|
||||
public enum ConnectionType
|
||||
{
|
||||
Unknown,
|
||||
Persistent, // 长连接
|
||||
Ephemeral, // 短连接
|
||||
Multicast, // 多播
|
||||
Loopback // 本地回环
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -104,7 +104,11 @@ public class EnhancedEtwNetworkManager : IDisposable
|
||||
RecordTime = tcpEvent.Timestamp,
|
||||
Direction = tcpEvent.Direction,
|
||||
IsPartialConnection = false,
|
||||
State = ConnectionState.Connecting
|
||||
State = ConnectionState.Connecting,
|
||||
// 明确标识这是增量还是累积值
|
||||
BytesSent = tcpEvent.DataLength, // 如果是增量
|
||||
BytesReceived = tcpEvent.DataLength,
|
||||
IsIncrementalData = true // 新增标识
|
||||
};
|
||||
|
||||
// 根据事件类型处理
|
||||
@@ -362,7 +366,8 @@ public class EnhancedEtwNetworkManager : IDisposable
|
||||
!c.IsActive && c.Duration > TimeSpan.FromMinutes(5)))
|
||||
{
|
||||
// 这里可以添加清理逻辑
|
||||
Console.WriteLine($"清理过期连接: {app.ProgramInfo?.ProductName} - {conn.RemoteIp}:{conn.RemotePort}");
|
||||
Console.WriteLine(
|
||||
$"清理过期连接: {app.ProgramInfo?.ProductName} - {conn.RemoteIp}:{conn.RemotePort}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -122,6 +122,9 @@ public sealed class GlobalNetworkMonitor
|
||||
/// <summary>
|
||||
/// 更新连接信息
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// 更新连接信息 - 修复版本
|
||||
/// </summary>
|
||||
public void UpdateConnectionInfo(NetworkModel networkModel)
|
||||
{
|
||||
_lock.EnterWriteLock();
|
||||
@@ -143,23 +146,83 @@ public sealed class GlobalNetworkMonitor
|
||||
LastActiveTime = networkModel.LastSeenTime,
|
||||
BytesSent = networkModel.BytesSent,
|
||||
BytesReceived = networkModel.BytesReceived,
|
||||
IsActive = networkModel.State == ConnectionState.Connected
|
||||
IsActive = networkModel.State == ConnectionState.Connected,
|
||||
|
||||
// 修复:正确初始化速度计算相关字段
|
||||
LastBytesSent = networkModel.BytesSent,
|
||||
LastBytesReceived = networkModel.BytesReceived,
|
||||
LastSpeedCalculationTime = networkModel.LastSeenTime,
|
||||
CurrentSendSpeed = 0,
|
||||
CurrentReceiveSpeed = 0,
|
||||
|
||||
// 📊 新增:重置计数器
|
||||
ResetCount = 0,
|
||||
TotalBytesSentAccumulated = networkModel.BytesSent,
|
||||
TotalBytesReceivedAccumulated = networkModel.BytesReceived
|
||||
},
|
||||
(key, existing) =>
|
||||
{
|
||||
// 更新基本信息
|
||||
existing.BytesSent = networkModel.BytesSent;
|
||||
existing.BytesReceived = networkModel.BytesReceived;
|
||||
existing.LastActiveTime = networkModel.LastSeenTime;
|
||||
existing.State = networkModel.State;
|
||||
existing.IsActive = networkModel.State == ConnectionState.Connected;
|
||||
|
||||
// 计算速率
|
||||
// 📈 改进的速率计算
|
||||
var timeDiff = (networkModel.LastSeenTime - existing.LastSpeedCalculationTime).TotalSeconds;
|
||||
if (timeDiff > 0)
|
||||
if (timeDiff > 0.1) // 避免时间间隔过小
|
||||
{
|
||||
existing.CurrentSendSpeed = (networkModel.BytesSent - existing.LastBytesSent) / timeDiff;
|
||||
existing.CurrentReceiveSpeed =
|
||||
(networkModel.BytesReceived - existing.LastBytesReceived) / timeDiff;
|
||||
var sentDiff = networkModel.BytesSent - existing.LastBytesSent;
|
||||
var receivedDiff = networkModel.BytesReceived - existing.LastBytesReceived;
|
||||
|
||||
// 🔄 智能重置检测
|
||||
bool sentReset = DetectCounterReset(existing.LastBytesSent, networkModel.BytesSent, timeDiff);
|
||||
bool receivedReset = DetectCounterReset(existing.LastBytesReceived, networkModel.BytesReceived,
|
||||
timeDiff);
|
||||
|
||||
if (sentReset)
|
||||
{
|
||||
existing.ResetCount++;
|
||||
existing.TotalBytesSentAccumulated += networkModel.BytesSent;
|
||||
sentDiff = networkModel.BytesSent; // 使用当前值作为增量
|
||||
|
||||
// 🔕 减少日志噪音:只记录重要的重置
|
||||
if (ShouldLogReset(existing.Protocol, existing.LocalEndpoint.Port, existing.ResetCount))
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"[信息] 连接 {connectionKey} 发送计数器重置 #{existing.ResetCount}: {existing.LastBytesSent} -> {networkModel.BytesSent}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
existing.TotalBytesSentAccumulated = Math.Max(existing.TotalBytesSentAccumulated,
|
||||
existing.TotalBytesSentAccumulated + sentDiff);
|
||||
}
|
||||
|
||||
if (receivedReset)
|
||||
{
|
||||
existing.ResetCount++;
|
||||
existing.TotalBytesReceivedAccumulated += networkModel.BytesReceived;
|
||||
receivedDiff = networkModel.BytesReceived;
|
||||
|
||||
if (ShouldLogReset(existing.Protocol, existing.LocalEndpoint.Port, existing.ResetCount))
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"[信息] 连接 {connectionKey} 接收计数器重置 #{existing.ResetCount}: {existing.LastBytesReceived} -> {networkModel.BytesReceived}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
existing.TotalBytesReceivedAccumulated = Math.Max(existing.TotalBytesReceivedAccumulated,
|
||||
existing.TotalBytesReceivedAccumulated + receivedDiff);
|
||||
}
|
||||
|
||||
// 计算速率(确保非负)
|
||||
existing.CurrentSendSpeed = Math.Max(0, Math.Abs(sentDiff) / timeDiff);
|
||||
existing.CurrentReceiveSpeed = Math.Max(0, Math.Abs(receivedDiff) / timeDiff);
|
||||
|
||||
// 更新记录值
|
||||
existing.LastBytesSent = networkModel.BytesSent;
|
||||
existing.LastBytesReceived = networkModel.BytesReceived;
|
||||
existing.LastSpeedCalculationTime = networkModel.LastSeenTime;
|
||||
@@ -168,6 +231,7 @@ public sealed class GlobalNetworkMonitor
|
||||
return existing;
|
||||
});
|
||||
|
||||
|
||||
// 更新进程的活跃连接列表
|
||||
if (_processes.TryGetValue(networkModel.ProcessId, out var process))
|
||||
{
|
||||
@@ -177,14 +241,16 @@ public sealed class GlobalNetworkMonitor
|
||||
}
|
||||
}
|
||||
|
||||
// 更新端口流量统计
|
||||
UpdatePortTraffic(networkModel.SourcePort, networkModel.BytesSent, networkModel.BytesReceived, true);
|
||||
UpdatePortTraffic(networkModel.DestinationPort, networkModel.BytesSent, networkModel.BytesReceived, false);
|
||||
|
||||
// 更新IP流量统计
|
||||
UpdateIpTraffic(networkModel.SourceIp.ToString(), networkModel.BytesSent, networkModel.BytesReceived, true);
|
||||
UpdateIpTraffic(networkModel.DestinationIp.ToString(), networkModel.BytesSent, networkModel.BytesReceived,
|
||||
// 更新端口流量统计(也需要类似的保护)
|
||||
UpdatePortTrafficSafe(networkModel.SourcePort, networkModel.BytesSent, networkModel.BytesReceived, true);
|
||||
UpdatePortTrafficSafe(networkModel.DestinationPort, networkModel.BytesSent, networkModel.BytesReceived,
|
||||
false);
|
||||
|
||||
// 更新IP流量统计(也需要类似的保护)
|
||||
UpdateIpTrafficSafe(networkModel.SourceIp.ToString(), networkModel.BytesSent, networkModel.BytesReceived,
|
||||
true);
|
||||
UpdateIpTrafficSafe(networkModel.DestinationIp.ToString(), networkModel.BytesSent,
|
||||
networkModel.BytesReceived, false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -192,6 +258,145 @@ public sealed class GlobalNetworkMonitor
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 🧠 智能检测计数器重置
|
||||
/// </summary>
|
||||
private bool DetectCounterReset(long previousValue, long currentValue, double timeDiffSeconds)
|
||||
{
|
||||
// 如果当前值小于之前值,可能是重置
|
||||
if (currentValue < previousValue)
|
||||
{
|
||||
// 但需要排除一些误判情况
|
||||
var decrease = previousValue - currentValue;
|
||||
|
||||
// 如果减少量很小且时间间隔短,可能是数据延迟,不算重置
|
||||
if (decrease < 1024 && timeDiffSeconds < 1.0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 🔇 减少不必要的日志噪音
|
||||
/// </summary>
|
||||
private bool ShouldLogReset(ProtocolType protocol, int port, int resetCount)
|
||||
{
|
||||
// mDNS 多播连接,重置很常见,减少日志
|
||||
if (port == 5353)
|
||||
{
|
||||
return resetCount <= 2; // 只记录前2次
|
||||
}
|
||||
|
||||
// 本地回环连接,重置也比较常见
|
||||
if (port > 49152) // 动态端口范围
|
||||
{
|
||||
return resetCount <= 3;
|
||||
}
|
||||
|
||||
// UDP 连接重置更常见
|
||||
if (protocol == ProtocolType.UDP)
|
||||
{
|
||||
return resetCount <= 5;
|
||||
}
|
||||
|
||||
// TCP 连接重置较少见,都记录
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 安全的端口流量更新
|
||||
/// </summary>
|
||||
private void UpdatePortTrafficSafe(int port, long bytesSent, long bytesReceived, bool isLocal)
|
||||
{
|
||||
_portTraffic.AddOrUpdate(port,
|
||||
new PortTrafficInfo
|
||||
{
|
||||
Port = port,
|
||||
BytesSent = isLocal ? bytesSent : 0,
|
||||
BytesReceived = isLocal ? 0 : bytesReceived,
|
||||
LastUpdateTime = DateTime.Now
|
||||
},
|
||||
(key, existing) =>
|
||||
{
|
||||
// ✅ 修复:防止流量统计出现负数
|
||||
if (isLocal)
|
||||
{
|
||||
// 如果新值小于现有值,可能是计数器重置,累加当前值
|
||||
if (bytesSent < existing.BytesSent)
|
||||
{
|
||||
existing.BytesSent += bytesSent;
|
||||
}
|
||||
else
|
||||
{
|
||||
existing.BytesSent = bytesSent;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bytesReceived < existing.BytesReceived)
|
||||
{
|
||||
existing.BytesReceived += bytesReceived;
|
||||
}
|
||||
else
|
||||
{
|
||||
existing.BytesReceived = bytesReceived;
|
||||
}
|
||||
}
|
||||
|
||||
existing.LastUpdateTime = DateTime.Now;
|
||||
return existing;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 安全的IP流量更新
|
||||
/// </summary>
|
||||
private void UpdateIpTrafficSafe(string ip, long bytesSent, long bytesReceived, bool isSource)
|
||||
{
|
||||
_ipTraffic.AddOrUpdate(ip,
|
||||
new IpTrafficInfo
|
||||
{
|
||||
IpAddress = ip,
|
||||
BytesSent = isSource ? bytesSent : 0,
|
||||
BytesReceived = isSource ? 0 : bytesReceived,
|
||||
LastUpdateTime = DateTime.Now
|
||||
},
|
||||
(key, existing) =>
|
||||
{
|
||||
// ✅ 修复:防止流量统计出现负数
|
||||
if (isSource)
|
||||
{
|
||||
if (bytesSent < existing.BytesSent)
|
||||
{
|
||||
existing.BytesSent += bytesSent;
|
||||
}
|
||||
else
|
||||
{
|
||||
existing.BytesSent = bytesSent;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bytesReceived < existing.BytesReceived)
|
||||
{
|
||||
existing.BytesReceived += bytesReceived;
|
||||
}
|
||||
else
|
||||
{
|
||||
existing.BytesReceived = bytesReceived;
|
||||
}
|
||||
}
|
||||
|
||||
existing.LastUpdateTime = DateTime.Now;
|
||||
return existing;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新DNS解析信息
|
||||
/// </summary>
|
||||
|
||||
@@ -48,6 +48,11 @@ public class NetworkModel
|
||||
|
||||
public long BytesReceived { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否是增量数据
|
||||
/// </summary>
|
||||
public bool IsIncrementalData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连接状态
|
||||
/// </summary>
|
||||
@@ -87,7 +92,7 @@ public class NetworkModel
|
||||
/// 是否是完整会话【如果在软件打开前会话已经创建则不认为是完整会话】
|
||||
/// </summary>
|
||||
public required bool IsPartialConnection { get; set; }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 会话持续时间
|
||||
@@ -171,4 +176,4 @@ public enum TrafficDirection
|
||||
Inbound,
|
||||
Outbound,
|
||||
// Unknown
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user