首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何通过夏普卡普获得连续的数据包?

如何通过夏普卡普获得连续的数据包?
EN

Stack Overflow用户
提问于 2019-07-09 08:21:55
回答 2查看 491关注 0票数 0

目前,我正试图捕获通过一个名为EtherCAT的程序发送和接收的TwinCAT数据包。TwinCAT是Windows环境下EtherCAT通信的实时控制软件.这个程序用于每4ms与奴隶通信。

顺便说一下,我捕获了数据包,并注意到在分析过程中数据并不是连续的。因此,我插入了代码来检查捕获数据包的部分的时间差,并确认一些数据包比前一个数据包晚了20 in。

因为我可以在TwinCAT XAE工具中检查丢失的帧,我不认为数据包实际上是丢失的,我认为我的程序有一个问题。

下面是我的密码。

代码语言:javascript
运行
复制
public class EtherCATPacketCaptureService
{
    private const int PacketQueueSize = 1024;

    private object locker;  //<-Mutex
    private Queue<RawCapture> PacketQueue;  //<-패킷을 저장할 큐
    private WinPcapDevice _etherCATDevice;  //<-EtherCAT 통신 네트워크 장치

    public int PacketsCount { get => PacketQueue.Count; }

    //생성자 : _etherCATDevice 객체와 EtherCAT통신장치 매칭 
    public EtherCATPacketCaptureService(string etherCATNICAddr)
    {
        CaptureDeviceList devices = CaptureDeviceList.Instance;

        if (devices.Count() < 1)
        {
            throw new Exception("Not exist network interface");
        }

        foreach (WinPcapDevice dev in devices)
        {
            if (dev.Addresses.Count > 0)
            {
                foreach (PcapAddress addr in dev.Addresses)
                {
                    if (addr.Addr.hardwareAddress != null)
                    {
                        string HWAddr = addr.Addr.hardwareAddress.ToString();
                        if (HWAddr == etherCATNICAddr)  // EtherCAT NIC MAC주소를 EtherCATNICAddr파라미터로 넘겨받아 설정
                        {
                            _etherCATDevice = dev;
                        }
                    }
                }
            }
        }

        if (_etherCATDevice == null)
            throw new NullReferenceException("Can't find EtherCAT NIC");
        else
        {
            PacketQueue = new Queue<RawCapture>(PacketQueueSize);
            locker = new object();
            _etherCATDevice.OnPacketArrival += Device_OnPacketArrival;
            _etherCATDevice.Open(OpenFlags.Promiscuous, 1000);
        }
    }

    ~EtherCATPacketCaptureService()
    {
        _etherCATDevice.Close();
    }

    //패킷 캡쳐 시작
    public void StartCapture(int timeout)
    {
        if(_etherCATDevice != null)
        {
            _etherCATDevice.StartCapture();
        }
    }

    //패킷 캡쳐 종료
    public void StopCapture()
    {
        if (_etherCATDevice != null)
        {
            _etherCATDevice.StopCapture();
        }
    }

    //패킷캡쳐 이벤트 발생 시 패킷을 큐메모리에 저장
    private void Device_OnPacketArrival(object sender, SharpPcap.CaptureEventArgs e)
    {
        if (_etherCATDevice != null)
        {
            lock (locker)
            {
                if (PacketQueue != null)
                {
                    if (PacketQueue.Count > 0)
                    {
                        if((e.Packet.Timeval.Date.Ticks - PacketQueue.Peek().Timeval.Date.Ticks) > 200000)
                            throw new Exception("Packet Droped");
                    }
                    PacketQueue.Enqueue(e.Packet);
                }
            }
        }
    }

    //저장된 패킷을 리턴(Dequeue)
    public RawCapture[] GetPackets(int count)
    {
        RawCapture[] PacketArray;
        if (_etherCATDevice != null)
        {
            lock (locker)
            {
                if (count >= PacketQueue.Count)
                    PacketArray = new RawCapture[PacketQueue.Count];
                else
                    PacketArray = new RawCapture[count];

                for (int i = 0; i < PacketArray.Length; i++)
                {
                    PacketArray[i] = PacketQueue.Dequeue();
                }
            }
            return PacketArray;
        }
        else
            return null;
    }

    public RawCapture[] GetPackets()
    {
        RawCapture[] PacketArray;
        if (_etherCATDevice != null)
        {
            lock (locker)
            {
                PacketArray = new RawCapture[PacketQueue.Count];

                for (int i = 0; i < PacketArray.Length; i++)
                {
                    PacketArray[i] = PacketQueue.Dequeue();
                }
            }
            return PacketArray;
        }
        else
            return null;
    }

    //저장된 패킷 클리어
    public void ClearPackets()
    {
        lock (locker)
        {
            PacketQueue.Clear();
        }
    }
}

OnPacketArrival的事件处理程序是Device_OnPacketArrival,如果它在处理程序中发现与前一个数据包的时间不同的20 is或更多的差异,就会导致抛出异常来检测问题。

这是因为我的表现不好而产生的问题吗?性能改进能得到解决吗?如果你有一个好的意见,请回答。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-09 14:42:50

如果您不是为了好玩或出于教育目的而编程,而是为了专业用途,我建议您使用Wireshark和一个名为ET2000的额外硬件来分析您的机器的Ethercat数据包。

ET2000添加一个带有最大时间戳的时间戳。延迟40 be,镜像包发送到pc,您将能够阅读感谢EtherCAT堆栈链接分解在wireshark。

票数 0
EN

Stack Overflow用户

发布于 2021-03-25 12:16:23

我们在EtherCAT和PROFINET捕获方面也有类似的问题。我们从那时起就使用了Hilscher netANALYZER工具,现在一切都很好。这些工具内置了硬件水龙头,因此延迟小于1ns。时间戳分辨率也是1ns。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56948279

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档