问候,
我有一种捕获数据包的方法。捕获后我想实时添加每个数据包作为listview中的一行,所以一旦我捕获数据包,我想将它添加到列表视图中。
当我使用items.Add()时我会得到重载参数错误的问题。 请指教!!
这是我的代码:
private void packetCapturingThreadMethod() {
Packet packet = null;
int countOfPacketCaptures = 0;
while ((packet = device.GetNextPacket()) != null)
{
packet = device.GetNextPacket();
if (packet is TCPPacket)
{
TCPPacket tcp = (TCPPacket)packet;
myPacket tempPacket = new myPacket();
tempPacket.packetType = "TCP";
tempPacket.sourceAddress = Convert.ToString(tcp.SourceAddress);
tempPacket.destinationAddress = Convert.ToString(tcp.DestinationAddress);
tempPacket.sourcePort = Convert.ToString(tcp.SourcePort);
tempPacket.destinationPort = Convert.ToString(tcp.DestinationPort);
tempPacket.packetMessage = Convert.ToString(tcp.Data);
packetsList.Add(tempPacket);
string[] row = { packetsList[countOfPacketCaptures].packetType, packetsList[countOfPacketCaptures].sourceAddress, packetsList[countOfPacketCaptures].destinationAddress, packetsList[countOfPacketCaptures].sourcePort, packetsList[countOfPacketCaptures].destinationPort, packetsList[countOfPacketCaptures].packetMessage };
try {
listView1.Items.Add(packetsList[countOfPacketCaptures].packetType, packetsList[countOfPacketCaptures].sourceAddress, packetsList[countOfPacketCaptures].destinationAddress, packetsList[countOfPacketCaptures].sourcePort, packetsList[countOfPacketCaptures].destinationPort, packetsList[countOfPacketCaptures].packetMessage)
; countOfPacketCaptures++;
lblCapturesLabels.Text = Convert.ToString(countOfPacketCaptures);}
catch (Exception e) { }
}
else if (packet is UDPPacket)
{
UDPPacket udp = (UDPPacket)packet;
myPacket tempPacket = new myPacket();
tempPacket.packetType = "UDP";
tempPacket.sourceAddress = Convert.ToString(udp.SourceAddress);
tempPacket.destinationAddress = Convert.ToString(udp.DestinationAddress);
tempPacket.sourcePort = Convert.ToString(udp.SourcePort);
tempPacket.destinationPort = Convert.ToString(udp.DestinationPort);
tempPacket.packetMessage = Convert.ToString(udp.Data);
packetsList.Add(tempPacket);
string[] row = { packetsList[countOfPacketCaptures].packetType, packetsList[countOfPacketCaptures].sourceAddress, packetsList[countOfPacketCaptures].destinationAddress, packetsList[countOfPacketCaptures].sourcePort, packetsList[countOfPacketCaptures].destinationPort, packetsList[countOfPacketCaptures].packetMessage };
try { dgwPacketInfo.Rows.Add(row);
countOfPacketCaptures++;
lblCapturesLabels.Text = Convert.ToString(countOfPacketCaptures);
}
catch (Exception e) { }
}
}
}
答案 0 :(得分:5)
那是因为Add方法不接受随机的参数序列。它只接受这里提到的类型的参数:
答案 1 :(得分:3)
除了logicnp所说的,我的猜测是你在一个单独的线程上运行你的 while 循环(因为否则它会阻止UI线程)。
修复初始问题后,您需要跨线程边界正确更新UI元素。
这是解释问题和解决方案的tutorial。
答案 2 :(得分:2)
这实际上只是你迄今为止给出的建议的综合。
到目前为止已经给出的要点是:
代码如下:
public partial class Form1 : Form
{
private readonly Device _device;
private readonly PacketBinder _packetBinder;
public Form1()
{
InitializeComponent();
_device = Device.GetInstance();
_packetBinder = PacketBinder.GetInstance(listView1);
var thread = new Thread(WritePackets);
thread.IsBackground = true;
thread.Start();
}
private void WritePackets()
{
Packet packet = null;
int countOfPacketCaptures = 0;
while ((packet = _device.GetNextPacket()) != null)
{
packet = _device.GetNextPacket();
MyPacket tempPacket = null;
if (packet is TCPPacket)
{
TCPPacket tcp = (TCPPacket)packet;
tempPacket = MyPacket.GetInstance();
tempPacket.PacketType = "TCP";
tempPacket.SourceAddress = Convert.ToString(tcp.SourceAddress);
tempPacket.DestinationAddress =
Convert.ToString(tcp.DestinationAddress);
tempPacket.SourcePort = Convert.ToString(tcp.SourcePort);
tempPacket.DestinationPort = Convert.ToString(tcp.DestinationPort);
tempPacket.PacketMessage = Convert.ToString(tcp.Data);
}
else if (packet is UDPPacket)
{
UDPPacket udp = (UDPPacket)packet;
tempPacket = MyPacket.GetInstance();
tempPacket.PacketType = "UDP";
tempPacket.SourceAddress = Convert.ToString(udp.SourceAddress);
tempPacket.DestinationAddress =
Convert.ToString(udp.DestinationAddress);
tempPacket.SourcePort = Convert.ToString(udp.SourcePort);
tempPacket.DestinationPort = Convert.ToString(udp.DestinationPort);
tempPacket.PacketMessage = Convert.ToString(udp.Data);
}
if (tempPacket != null)
{
_packetBinder.AddPacketToView(tempPacket);
}
}
}
}
internal class Device
{
private Device() { }
internal static Device GetInstance()
{
return new Device();
}
internal Packet GetNextPacket()
{
var random = new Random();
var coin = random.Next(2);
Thread.Sleep(500);
if (coin == 0)
{
return new TCPPacket()
{
Data = GetRandomString(random),
SourceAddress = GetRandomString(random),
SourcePort = random.Next(),
DestinationAddress = GetRandomString(random),
DestinationPort = random.Next()
};
}
else
{
return new UDPPacket()
{
Data = GetRandomString(random),
SourceAddress = GetRandomString(random),
SourcePort = random.Next(),
DestinationAddress = GetRandomString(random),
DestinationPort = random.Next()
};
}
}
private string GetRandomString(Random random)
{
var bytes = new byte[16];
random.NextBytes(bytes);
return Convert.ToBase64String(bytes);
}
}
internal class MyPacket
{
private MyPacket() { }
internal static MyPacket GetInstance()
{
return new MyPacket();
}
internal string PacketType { get; set; }
internal string SourceAddress { get; set; }
internal string DestinationAddress { get; set; }
internal string SourcePort { get; set; }
internal string DestinationPort { get; set; }
internal string PacketMessage { get; set; }
}
internal class ThreadSafeListViewMutator
{
private readonly ListView _target;
private ThreadSafeListViewMutator(ListView target)
{
_target = target;
}
internal static ThreadSafeListViewMutator GetInstance(ListView target)
{
return new ThreadSafeListViewMutator(target);
}
internal void AddListViewItem(ListViewItem listItem)
{
Action action = () => _target.Items.Add(listItem);
Delegate asDelegate = action;
var handle = _target.BeginInvoke(asDelegate);
_target.EndInvoke(handle);
}
}
internal class PacketBinder
{
private readonly ThreadSafeListViewMutator _target;
private PacketBinder(ListView target)
{
_target = ThreadSafeListViewMutator.GetInstance(target);
}
internal static PacketBinder GetInstance(ListView target)
{
return new PacketBinder(target);
}
internal void AddPacketToView(MyPacket tempPacket)
{
var listItem = new ListViewItem() { Text = tempPacket.PacketType };
AddSubItem(listItem, "From", tempPacket.SourceAddress + ":"
+ tempPacket.SourcePort);
AddSubItem(listItem, "To", tempPacket.DestinationAddress + ":"
+ tempPacket.DestinationPort);
AddSubItem(listItem, "Message", tempPacket.PacketMessage);
_target.AddListViewItem(listItem);
}
private void AddSubItem(ListViewItem listItem, string attribute, string value)
{
listItem.Text = listItem.Text + @"
" + attribute + " = " + value;
}
}
internal class Packet { }
// Are these really duplicated this way? Seems crazy...
internal class TCPPacket : Packet
{
internal string SourceAddress { get; set; }
internal string DestinationAddress { get; set; }
internal int SourcePort { get; set; }
internal int DestinationPort { get; set; }
internal string Data { get; set; }
}
internal class UDPPacket : Packet
{
internal string SourceAddress { get; set; }
internal string DestinationAddress { get; set; }
internal int SourcePort { get; set; }
internal int DestinationPort { get; set; }
internal string Data { get; set; }
}
答案 3 :(得分:1)
此外,一旦你开始工作,重构创建一个继承自listview的类,并添加你自己的重载Add方法,它接受你所有类的完整对象,并将它们适当地添加到listview中 - 这将为你节省一些代码重复并使您的代码更清晰,更易读和可维护。