1

I'm using SharpPCap to collect IEC61850-9-2LE Sampled Values over Ethernet. IEC61850-9-2LE Sampled Values consists of several streams, each one sending 4000 packets per second, where the avg packet size is 125 bytes.

Using SharpPCap I'm trying to collect 3 of those streams (3x4000 packets per second - 125bytes each).

In the following code I set up the Network Interface Card.

if (nicToUse != null)
         {
            try
            {
               nicToUse.OnPacketArrival -= OnPackectArrivalLive;
               nicToUse.OnPacketArrival += OnPackectArrivalLive;
               try
               {
                  if (nicToUse.Started)
                     nicToUse.StopCapture();
                  if (nicToUse.Opened)
                     nicToUse.Close();
               }
               catch (Exception)
               {
                  //no handling, just do it.
               }

               nicToUse.Open(OpenFlags.Promiscuous|OpenFlags.MaxResponsiveness,10);

               var kernelBufferAssigned = false;
               uint kernelBufferSize = 200;

               while (!kernelBufferAssigned)
               {
                  try
                  {
                     nicToUse.KernelBufferSize = kernelBufferSize * 1024 * 1024;
                     kernelBufferAssigned = true;
                  }
                  catch (Exception)
                  {
                     kernelBufferSize--;
                  }

               }

               nicToUse.Filter = "(ether[0:4] = 0x010CCD04)";
               watchdog.Enabled = true;
               counter = 0;
               nicToUse.StartCapture();
            }
            catch (Exception ex)
            {
               throw new Exception(Resources.SharpPCapPacketsProducer_Start_Error_while_starting_online_capture_, ex);
            }
         }

This is the OnPacketArrival event handler:

private void OnPackectArrivalLive(object sender, CaptureEventArgs e)
      {
         try
         {
            counter++;
            circularBuffer[circularBufferIndex] = e.Packet;
            circularBufferIndex++;

            if (circularBufferIndex > circularBufferSize - 1)
               circularBufferIndex = 0;

         }
         catch (Exception)
         {

         }
      }

When the capturing is over (user stops it), the captured packets are decoded and since they hold a sequential counter I've discovered some samples are missing.

Connecting the same source to another PC running Wireshark, those samples are not missing.

Any idea ?

Lorenzo Santoro
  • 464
  • 1
  • 6
  • 16

1 Answers1

1

What version of SharpPcap are you using? There have been some pretty big performance improvements due to overhead reduction in the 3.x and 4.x series.

Your example seems to be wrapping the circular buffer around at the tail. What type is circularBuffer? How are you sure that you are processing the packets before your buffer has filled up?

Have you looked at this example, from the SharpPcap source distribution, that shows one technique for doing background packet processing?

QueueingPacketsForBackgroundProcessing/Main.cs

Chris Morgan
  • 1,277
  • 1
  • 13
  • 33
  • Ciao Chris, thanks for your support. I'm currently using 4.1.0.0 – Lorenzo Santoro Mar 14 '13 at 14:05
  • The circular buffer is wrapping around the tail because, I'm interested in processing only a limited and fixed number of packets. private RawCapture[] circularBuffer; I am *not* decoding the packets before placing them in buffer, but I'm just collecting them all. I think I got your point: I'm not losing packets because of the circularbuffer. I want to collect only the very last 500000 packets. When the user stops, he wants to be sure that he is going to process only the last 500000 packets. – Lorenzo Santoro Mar 14 '13 at 14:21
  • The fact is that each packet belonging to a single stream has a counter going from 0 to 3999: so, for example, a packet belonging to stream A can have counter #2333, and the next packet of the very stream A will have counter #2334. After decoding the packets, I've realized that I jump from i.e. 2333 to 2347. I hope it was clear enough. Your example is great, but I don't need "online decoding", it's fine to store the packets somewhere while capturing, and process them after. I hope I was clear enough. – Lorenzo Santoro Mar 14 '13 at 14:23
  • Ahh I see. With the circular buffer you are already using a similar technique to the background queuing approach. Are you preallocating the RawCapture array to be the appropriate size? It may be that .Net is reallocating the entire array to resize it in some inefficient manner. You might simplify your example to store some smaller number of packets and see if you are still seeing missed packets. SharpPcap should be able to configure the adapter in the same manner that wireshark does but clearly there is some overhead with .Net that we need to be careful about. – Chris Morgan Mar 14 '13 at 16:21
  • Yes, the circularBuffer is allocated to its maximum size within the constructor. I've tried to use a very small array, 5000 samples in place of 500000, but the result is still the same: missing sample. – Lorenzo Santoro Mar 15 '13 at 09:17