سؤال

مرحبا، أحاول تحويل الحزمة التي التقاطها في Example3 في SHARPPCAP الإصدار الجديد Sharppcap-2.2.0rc1.src من تطبيق Console إلى تطبيق نماذج Windows.

إنني مواجهة مشكلة عندما حاولت إضافة حزم إلى ListView Control، سأحصل على خطأ هو:

(العملية عبر مؤشر الترابط غير صالحة: التحكم "ListViewStackets" الوصول إليها من مؤشر ترابط آخر غير مؤشر الترابط الذي تم إنشاؤه عليه.)

في هذا الخط:
listViewPackets.Items.Add(e.Packet.ToString());

أي نصيحة لحل هذه المشكلة ؟؟

هنا هو رمزي:

using SharpPcap;

namespace Packets
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }



            // Retrieve the device list

        private void btnLiDevicest_Click(object sender, EventArgs e)
        {
            var devices = LivePcapDeviceList.Instance;
            // If no devices were found print an error
            if (devices.Count < 1)
            {
                MessageBox.Show("No devices were found on this machine");
                return;
            }


            int i = 0;

            // Print out the devices
            foreach (LivePcapDevice dev in devices)
            {

                ///* Description */
                //Console.WriteLine("{0}) {1} {2}", i, dev.Name, dev.Description);
                cmbListDevice.Items.Add(dev.Name + "   " + dev.Description);
                i++;
            }
           LivePcapDevice device = devices[1];
            // Register our handler function to the 'packet arrival' event
            device.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrival);

            // Open the device for capturing
            int readTimeoutMilliseconds = 1000;
            device.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
            device.StartCapture();


        }


            //Console.WriteLine();
            //Console.WriteLine("-- Listening on {0}, hit 'Enter' to stop...",
            //    device.Description);
                    /// <summary>
        /// Prints the time and length of each received packet
        /// </summary>
        /// 

        protected  void device_OnPacketArrival(object sender, CaptureEventArgs e)
        {
            DateTime time = e.Packet.PcapHeader.Date;
            uint len = e.Packet.PcapHeader.PacketLength;
            //Console.WriteLine("{0}:{1}:{2},{3} Len={4}", 
            //    time.Hour, time.Minute, time.Second, time.Millisecond, len);

           // Console.WriteLine(e.Packet.ToString());

            listViewPackets.Items.Add(e.Packet.ToString());


        }



        }


}

................................................. ................... هنا هو الرمز الأصلي:

using System;
using System.Collections.Generic;
using SharpPcap;
namespace SharpPcap.Test.Example3
{
    /// <summary>
    /// Basic capture example
    /// </summary>
    public class BasicCap
    {
        public static void Main(string[] args)
        {
            // Print SharpPcap version
            string ver = SharpPcap.Version.VersionString;
            Console.WriteLine("SharpPcap {0}, Example3.BasicCap.cs", ver);

            // Retrieve the device list
            var devices = LivePcapDeviceList.Instance;

            // If no devices were found print an error
            if(devices.Count < 1)
            {
                Console.WriteLine("No devices were found on this machine");
                return;
            }

            Console.WriteLine();
            Console.WriteLine("The following devices are available on this machine:");
            Console.WriteLine("----------------------------------------------------");
            Console.WriteLine();

            int i = 0;

            // Print out the devices
            foreach(LivePcapDevice dev in devices)
            {
                /* Description */
                Console.WriteLine("{0}) {1} {2}", i, dev.Name, dev.Description);
                i++;
            }

            Console.WriteLine();
            Console.Write("-- Please choose a device to capture: ");
            i = int.Parse( Console.ReadLine() );

            LivePcapDevice device = devices[i];

            // Register our handler function to the 'packet arrival' event
            device.OnPacketArrival += 
                new PacketArrivalEventHandler( device_OnPacketArrival );

            // Open the device for capturing
            int readTimeoutMilliseconds = 1000;
            device.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);

            Console.WriteLine();
            Console.WriteLine("-- Listening on {0}, hit 'Enter' to stop...",
                device.Description);

            // Start the capturing process
            device.StartCapture();

            // Wait for 'Enter' from the user.
            Console.ReadLine();

            // Stop the capturing process
            device.StopCapture();

            Console.WriteLine("-- Capture stopped.");

            // Print out the device statistics
            Console.WriteLine(device.Statistics().ToString());

            // Close the pcap device
            device.Close();
        }

        /// <summary>
        /// Prints the time and length of each received packet
        /// </summary>
        private static void device_OnPacketArrival(object sender, CaptureEventArgs e)
        {
            DateTime time = e.Packet.PcapHeader.Date;
            uint len = e.Packet.PcapHeader.PacketLength;
            Console.WriteLine("{0}:{1}:{2},{3} Len={4}", 
                time.Hour, time.Minute, time.Second, time.Millisecond, len);
            Console.WriteLine(e.Packet.ToString());
        }
    }
}
هل كانت مفيدة؟

المحلول

عند إجراء مكالمة للتحكم من مؤشر ترابط آخر:

if (listView1.InvokeRequired)
{
    listView1.BeginInvoke(new MethodInvoker(
        () => /*whatever you want with listview */));
}
else
{
    /* whatever you want with listview */
}

إذا كنت تعرف بالتأكيد أنه سيكون دائما في مؤشر ترابط آخر، فما عليك سوى ننسى if / آخر واستخدام الدعارة.

تعديل:

لذلك في قضيتك، يبدو الأمر كذلك:

if(listView1.InvokeRequired)
{
    listView1.BeginInvoke(new MethodInvoker(
        () => listViewPackets.Items.Add(e.Packet.ToString()) ));
}
else
{
    listViewPackets.Items.Add(e.Packet.ToString());
}

(مرة أخرى، أو مجرد مكالمة BeginInvoke، إذا كان سيتم تشغيله دائما مؤشر ترابط مختلف)

تحرير 2 ستلاحظ أن Shane يستخدم استدعاء واستخدم BeginInvoke. أنا استخدمها كقوة من العادة. سوف يحظر استخدام Invoke على مؤشر ترابط UI، وإذا كنت تقوم بعملية تستغرق وقتا أطول، فاستخدم BeginInvoke يقوم بتنفيذ التحديث إلى UI غير متزامن.

نصائح أخرى

تحتاج إلى استخدام يستحضر لأن الحزمة تأتي في مؤشر ترابط مختلف. لا يمكن تعديل ضوابط UI على مؤشر ترابط آخر غير المرء الذي تم إنشاؤه عليه. سوف يستدعي تنفيذ المندوب المحدد على موضوع UI. على سبيل المثال، يمكنك القيام بذلك:

this.Invoke(new MethodInvoker(() => listViewPackets.Items.Add(e.Packet.ToString())), null);

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top