見つけられない迷惑なバグがあり、助けていただければ幸いです。
Wireshark
ファイル(Pcapファイル)を取得してパケットを再生するアプリケーションがありPcap.Net project
、ファイルを自分のファイルに追加し、
実際にパケット呼び出しを再生するクラスをListbox
クリックするだけ
で、アプリケーションを次のように構築します。play button
WiresharkFile
すべてのファイルを my に追加し、Listbox
play という名前の別のクラスをクリックした後、すべてのファイルJob
のコンストラクタ リストで受け取ったファイルと、ファイルの呼び出しWiresharkFile
と再生を担当するこのクラス。
これは私のJob
クラスです:
using packetPlayer;
using PcapDotNet.Core;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace PacketPlayer.classes
{
public class Job
{
private decimal _loopCount;
private int _currentFileNum;
private bool _shouldContinue;
public bool shouldContinue
{
get { return _shouldContinue; }
set
{
_shouldContinue = value;
if (!_shouldContinue)
{
foreach (WiresharkFile wf in wiresharkFileList)
{
wf.setIsStop(false);
wf.setStopButton(false);
}
}
}
}
private IEnumerable<string> _source;
private PacketDevice _selectedOutputDevice;
private double _speed;
private int _parallelThreads;
private decimal _loops;
public CancellationTokenSource _tokenSource { get; set; }
public delegate void StatusChangedDelegate(WiresharkFile wiresharkFile);
public event StatusChangedDelegate statusChangedEvent;
public Job(IEnumerable<string> source, PacketDevice selectedOutputDevice, double speed, int parallelThreads, decimal loops)
{
_source = source;
_selectedOutputDevice = selectedOutputDevice;
_speed = speed;
_parallelThreads = parallelThreads;
_loops = loops;
_loopCount = 0;
}
public void doWork()
{
wiresharkFileList = new List<WiresharkFile>();
_currentFileNum = 1;
_shouldContinue = true;
_tokenSource = new CancellationTokenSource();
var token = _tokenSource.Token;
Task.Factory.StartNew(() =>
{
try
{
Parallel.ForEach(_source,
new ParallelOptions
{
MaxDegreeOfParallelism = _parallelThreads //limit number of parallel threads
},
file =>
{
if (token.IsCancellationRequested)
return;
processFile(file, _selectedOutputDevice, _speed);
_currentFileNum++;
});
}
catch (Exception)
{ }
}, _tokenSource.Token).ContinueWith(
t =>
{
_loopCount++;
if (continueAnotherLoop())
doWork();
else
OnFinishPlayEvent();
}
, TaskScheduler.FromCurrentSynchronizationContext() //to ContinueWith (update UI) from UI thread
);
}
private void processFile(string file, PacketDevice selectedOutputDevice, double speed)
{
Capinfos fileDetails = getFileDetails(file);
WiresharkFile wiresharkFile = new WiresharkFile();
wiresharkFileList.Add(wiresharkFile);
wiresharkFile.startTimerEvent += wf_startTimerEvent;
wiresharkFile.stopTimerEvent += wf_stopTimerEvent;
wiresharkFile.statusChangedEvent += wf_statusChangedEvent;
FileDetailsEvent(new FileInfo(file).Name, fileDetails.packets, fileDetails.duration);
wiresharkFile.sendBuffer(file, selectedOutputDevice, speed, fileDetails.packets);
}
private Capinfos getFileDetails(string file)
{
Capinfos details = new Capinfos();
details.readNumberOfPackets(file);
details.readFileDuration(file);
return details;
}
private void wf_statusChangedEvent(WiresharkFile wiresharkFile)
{
statusChangedEvent(wiresharkFile);
}
public int currentFileNum
{
get { return _currentFileNum; }
}
private bool continueAnotherLoop()
{
if (_loopCount < _loops)
return true;
else
return false;
}
}
}
このクラスは、すべてのラベルを更新するためにStatusChangedEvent
現在のオブジェクトをフォームに渡しWiresharkFile
ます (WiresharkFile クラスにはいくつかのプロパティがあります)
これは、タイマーを開始し、200 ミリ秒ごとに GUI を更新する形式のイベントです。
Timer timerPacket;
private void job_startTimerEvent(WiresharkFile wiresharkFile)
{
timerPacket.Tag = wiresharkFile;
if (InvokeRequired)
this.Invoke((MethodInvoker)delegate
{
timerPacket.Start();
});
else
{
timerPacket.Start();
}
}
今はすべて正常に動作し、すべてのラベルが更新されていますが、奇妙なバグがあります: 複数のファイルを選択するとすべて正常に動作しますが、たとえば 1 つのファイルを選択し、このファイルを 2 回再生することを選択した場合、最初の反復は完璧に機能しますが、2 番目の反復では私のタイマーを止めていないのにタイマーが始まらない