2013-03-14 118 views
1

我使用SharpPCap通过以太网收集IEC61850-9-2LE采样值。 IEC61850-9-2LE采样值由多个数据流组成,每个数据流每秒发送4000个数据包,其中平均数据包大小为125个字节。SharpPCap丢失数据包

使用SharpPCap我试图收集这些流中的3个(每秒3x4000包 - 每个125bytes)。

在下面的代码中,我设置了网络接口卡。

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); 
      } 
     } 

这是OnPacketArrival事件处理程序:

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

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

     } 
     catch (Exception) 
     { 

     } 
     } 

当拍摄结束(用户停止它),捕获的数据包进行解码,并因为他们持有顺序计数器,我发现了一些样品缺失。

将相同的源连接到另一台运行Wireshark的PC,这些示例不会丢失。

有什么想法?

回答

1

您使用的是什么版本的SharpPcap?由于3.x和4.x系列的开销减少,性能有了很大提升。

您的示例似乎是将环形缓冲区环绕在尾部。 circularBuffer是什么类型?您如何确定在缓冲区填满之前处理数据包?

您是否看过SharpPcap源代码发行版中的这个示例,该示例显示了一种用于执行后台数据包处理的技术?

QueueingPacketsForBackgroundProcessing/Main.cs

+0

Ciao Chris,感谢您的支持。 我目前正在使用4.1.0.0 – 2013-03-14 14:05:30

+0

循环缓冲区正在环绕尾部,因为我只想处理有限且固定数量的数据包。 private RawCapture [] circularBuffer; 我不*解码数据包,然后将它们放入缓冲区,但我只是将它们全部收集起来。 我想我明白了你的观点:由于循环缓冲,我不会丢失数据包。我只想收集最后的500000个数据包。当用户停下来时,他想确定他将只处理最后的500000个数据包。 – 2013-03-14 14:21:01

+0

事实是,属于单个流的每个分组具有从0到3999的计数器:因此,例如,属于流A的分组可以具有计数器#2333,并且流A的下一个分组将具有计数器#2334。 对数据包解码后,我意识到我从2333跳到2347. 我希望它已经足够清楚。 你的例子很棒,但我不需要“在线解码”,在捕获时把数据包存储在某个地方并在之后处理它们是很好的。 我希望我很清楚。 – 2013-03-14 14:23:06