这是我见过的最奇怪的问题,我希望你觉得它有趣。我创建了一个 C# WPF 示例,它作为典型的数据包嗅探器(来源如下)监听 IP 数据包,并将一些数据打印到屏幕上。我有非常一致和可重复的行为,但有两个结果(快和慢)。
先决条件:由于 IP 套接字代码,以管理员身份运行 Visual Studio 2010。
如果我在 Visual Studio 中以 x86 Release模式运行应用程序(单击绿色箭头),它每秒处理大约 300 个数据包(快速)。完美的。如果我在 Debug模式下运行它,它每秒处理大约 1 个数据包(慢)。这是可以理解的,因为 Debug模式会增加开销。但是,等等,这就是奇怪的地方。
问题/疑问:
如果我将解决方案复制到另一个文件夹并从 Visual Studio 中运行(与以前一样的 x86 版本),它运行缓慢。但是,如果我将相同的解决方案复制回原始文件夹路径,它运行得很快。为什么?
如果我从命令提示符以管理员身份运行 x86 Release模式可执行文件,它每秒处理大约 1 个(慢)。为什么? (编辑:这可能是因为 VS 托管过程带来的任何性能提升在 VS 之外都不存在。)
因此,代码只有在原始文件夹中从 Visual Studio(x86 版本)运行时才能快速执行。
我尝试过的其他事情:
- 清理并手动修改 obj 和 bin 文件夹...并重建解决方案。
- 清理注册表并删除所有引用应用程序或路径的行。
- 删除了 Windows 防火墙中引用该应用程序名称的所有条目。
- 禁用防病毒软件并将该应用程序添加到排除列表。
- 运行 Visual Studio 输出文本的差异比较 (BeyondCompare)。
- 创建了新的解决方案并将代码复制/粘贴到其中,如果名称不同或不在同一文件夹中,它们仍然运行缓慢。
- 与每秒显示大约 300 个数据包的 WireShark 捕获相比。
- 启用/禁用 VS 主机进程。如果解决方案仅在原始路径中,则启用运行速度更快。
- 重新启动
MainWindow.xaml
<Window x:Class="WpfSingle.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Closing="Window_Closing">
<Grid>
<ScrollViewer>
<TextBlock Name="textBlock1"></TextBlock>
</ScrollViewer>
</Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Text;
using System.Windows;
using System.Net.Sockets;
using System.Net;
namespace WpfSingle
{
public partial class MainWindow : Window
{
private static System.Threading.Thread _processingThread;
private bool _killThread;
private Socket _socket;
private const int PACKET_MAX_SIZE = 32768;
private byte[] _bytesIn;
private byte[] _bytesOut;
private byte[] _byteData;
private int _bytesReceived;
private int _packetCounter;
private string Interface = "192.168.1.42";
private StringBuilder _sbTextOut;
public MainWindow()
{
InitializeComponent();
_sbTextOut = new StringBuilder();
try
{
_processingThread = new System.Threading.Thread(ThreadProcess);
_processingThread.Start();
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
}
}
private void ThreadProcess()
{
_killThread = false;
_byteData = new byte[PACKET_MAX_SIZE];
_bytesIn = new byte[4] { 1, 0, 0, 0 };
_bytesOut = new byte[4] { 1, 0, 0, 0 };
_packetCounter = 0;
try
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
_socket.Bind(new IPEndPoint(IPAddress.Parse(Interface), 0));
_socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);
_socket.IOControl(IOControlCode.ReceiveAll, _bytesIn, _bytesOut);
}
catch (Exception ex)
{
if (_socket != null) _socket.Close();
Console.Error.WriteLine(ex.Message);
}
while (true)
{
OnThreadProcess();
if (_killThread)
break;
}
}
private void OnThreadProcess()
{
if (_socket != null)
{
EndPoint ep = new IPEndPoint(IPAddress.Any, 0) as EndPoint;
try
{
_bytesReceived = _socket.ReceiveFrom(_byteData, _byteData.Length, SocketFlags.None, ref ep);
if (_bytesReceived > 0)
{
_packetCounter++;
if (_packetCounter >= 300) _killThread = true;
_sbTextOut.AppendLine(string.Format("{0} : {1} {2} {3} {4} {5} {6} {7}", DateTime.Now.ToString("H:mm:ss.ffffff"), _packetCounter, _byteData[0], _byteData[1], _byteData[2], _byteData[3], _byteData[4], _byteData[5]));
Dispatcher.Invoke(new Action(() =>
{
textBlock1.Text = _sbTextOut.ToString();
}));
}
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
}
}
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
_killThread = true;
}
}
}
最佳答案
不幸的是,代码现在在所有配置中都以很慢的速度捕获。我无法再获得 300/秒的数据包捕获。它现在正在运行/捕获大约 2-3/秒。是的,我使用的是相同的源代码。我确信问题与 vshosts 有关(感谢 Kris)。不幸的是,我仍然不知道如何重新创建更高的捕获率,而较慢的捕获率也不够好用。显然这是可能的,因为它整天都在快速运行……直到现在。感谢大家的帮助。
关于C# WPF 代码在 Visual Studio 中的运行速度比在控制台中的运行速度快,而在另一个文件夹中的运行速度较慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26680486/