U:处理网速可能为负数的问题

This commit is contained in:
jimmy committed 2025-07-03 15:48:31 +08:00
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
}
}