qq_40332177 2022-02-28 15:29 采纳率: 0%
浏览 65
已结题

sharPcap SendPacket发送的数据都变成了两条

SendPacket监听网卡后,通过SendPacket发送数据时,所有发送的数据都发送了两次。请问这个是什么问题?
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using PacketDotNet;
using SharpPcap;
using SharpPcap.AirPcap;
using SharpPcap.LibPcap;
using SharpPcap.WinPcap;

namespace DeviceSearch.Common
{
internal class SharPcapTest
{
private static object syncObj = new object();
private static SharPcapTest _capInstance;

    public static SharPcapTest WinCapInstance
    {
        get
        {
            if (null == _capInstance)
            {
                lock (syncObj)
                {
                    if (null == _capInstance)
                    {
                        _capInstance = new SharPcapTest();
                    }
                }
            }
            return _capInstance;
        }
    }

    /// <summary>
    /// 当前监听的网卡设备
    /// </summary>
    public PcapDevice _device;
    /// <summary>
    /// 当前监听的网卡设备的mac
    /// </summary>
    private string _mac;
    /// <summary>
    /// 当前监听的网卡设备的IP
    /// </summary>
    private string _ip;
    /// <summary>
    /// 监听线程
    /// </summary>
    public Thread _thread;
    /// <summary>
    /// 发送、监听端口
    /// </summary>
    public ushort _port = 4035;
    /// <summary>
    /// 过滤条件1,只监听udp协议并且是4035端口的数据
    /// </summary>
    public string filter = "udp and port 4035";
    /// <summary>
    /// 过滤条件2,过滤源端口非4035的数据
    /// </summary>
    public string filter2 = "SourcePort=4035";
    /// <summary>
    /// 过滤条件4,过滤目的端口非4035的数据
    /// </summary>
    public string filter4 = "DestinationPort=4035";
    /// <summary>
    /// 过滤条件3,过滤广播数据
    /// </summary>
    public string filter3 = "DestinationAddress=255.255.255.255";
    


    private SharPcapTest()
    {

    }

    public void getNetWorkInfo(string ipStr)
    {
        string ver = SharpPcap.Version.VersionString;
        //Console.WriteLine("版本:SharpPcap {0}", ver);

        // Retrieve the device list
        CaptureDeviceList devices = CaptureDeviceList.Instance;

        // If no devices were found print an error
        if (devices.Count < 1)
        {
            Console.WriteLine("没有查询到网卡设备");
        }

        // Print out the available network devices
        foreach (ICaptureDevice dev in devices)
        {
            //Console.WriteLine("{0}\n", dev.ToString());
            PcapDevice pDev = (PcapDevice)dev;
            PcapAddress pAddr = pDev.Interface.Addresses.Where(s=>s.Addr.ToString() == ipStr).FirstOrDefault();
            if (pAddr != null)
            {
                _ip = ipStr;
                _device = pDev;
                _mac = ArpHelper.FixMac(pDev.Interface.MacAddress.ToString());
                return;
            }
        }
    }


    public bool Listen()
    {
        if (_device == null) return false;

        //开启监听线程
        _thread = new Thread(new ThreadStart(() =>
        {
            _device.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrival);
            _device.Open(DeviceMode.Normal, 1000);
            _device.Capture(500);
            //_device.StartCapture();
        }));
        _thread.Start();

        return true;
    }


    private bool PrintPacket(Packet p)
    {
        if (p != null)
        {
            string s = p.ToString();
            if (!string.IsNullOrEmpty(filter2) && !s.Contains(filter2))
            {
                return false;
            }

            if (!string.IsNullOrEmpty(filter4) && !s.Contains(filter4))
            {
                return false;
            }

            if (!string.IsNullOrEmpty(filter3) && s.Contains(filter3))
            {
                return false;
            }

            return true;
        }
        return false;
    }

    private void device_OnPacketArrival(object sender, CaptureEventArgs e)
    {
        ////解析出基本包
        var packet = PacketDotNet.Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data);

        //过滤只处理通过指定过滤条件的数据包
        if (!PrintPacket(packet)) return;

        try
        {
            //解析成udp数据包
            var udp = (UdpPacket)packet.Extract(typeof(UdpPacket));
            EthernetPacket ethernet = packet as EthernetPacket;
            IPv4Packet pv4Packet = udp.ParentPacket as IPv4Packet;
            string sourceIp = pv4Packet.SourceAddress.ToString();
            string sourceMac = ethernet.SourceHwAddress.ToString();
            rec(udp.PayloadData, udp.PayloadData.Length, sourceMac, sourceIp);
        }
        catch (Exception ex)
        {
            LogHelper.RevLog(new StringBuilder().Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:FFF")).Append(" 解析数据失败:").Append(ex.Message).ToString());
        }
    }


    private void rec(byte[] buf, int size, string sourceMac, string sourceIp)
    {
        string UdpStr = "";
        StringBuilder sb = new StringBuilder();
        if (buf != null)
        {
            for (int i = 0; i < buf.Length; i++)
            {
                sb.Append(buf[i].ToString("X2"));
            }
            UdpStr = sb.ToString();
        }

        //接收的是单项编程扩展(从码为整数)命令,如果是发送的命令则跳过
        if (UdpStr.Length == 102)
        {
            string sbm = UdpStr.Substring(32, 2);
            if (sbm == "11" || sbm == "12" || sbm == "14" || sbm == "16" || sbm == "18" || sbm == "19")
            {
                return;
            }
        }

        //如果是发送的命令的应答命令
        if (UdpStr.Length == 16 && UdpStr.Substring(12, 2).ToLower() == "bc")
        {
            //string commId = int.Parse(UdpStr.Substring(2, 2), System.Globalization.NumberStyles.HexNumber).ToString();
            //string devId = int.Parse(UdpStr.Substring(4, 2), System.Globalization.NumberStyles.HexNumber).ToString();
            SendUdp.ValidAnswer(sourceMac);

            //LogHelper.RevLog(DateTime.Now.ToString() + "接收响应:" + UdpStr);
            return;
        }
        else if (UdpStr.Length == 102 && UdpStr.Substring(12, 2).ToLower() == "3c")
        {
            IPEndPoint ipEnd = new IPEndPoint(IPAddress.Parse(sourceIp), _port);
            Globel._Arrbuf.Add(new Model.RevData { Data = UdpStr,Ip = sourceIp, Mac = sourceMac });
            LogHelper.RevLog(new StringBuilder().Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:FFF")).Append(" 监听:").Append(UdpStr).ToString());
            CallBackUdp.Respond(UdpStr, CallBackUdp.udp, ipEnd);
        }
    }


    public void send(byte[] data, string sourceIp, string sourceMac)
    {
        //创建udp层数据包
        ushort udpSourcePort = _port;
        ushort udpDestinationPort = _port;
        var udpPacket = new UdpPacket(udpSourcePort, udpDestinationPort);
        udpPacket.PayloadData = data;
        
        //创建ip层数据包
        var ipSourceAddress = System.Net.IPAddress.Parse("10.0.0.31");
        var ipDestinationAddress = System.Net.IPAddress.Parse(sourceIp);
        var ipPacket = new IPv4Packet(ipSourceAddress, ipDestinationAddress);
        ipPacket.PayloadPacket = udpPacket;

        int sum1 = udpPacket.CalculateUDPChecksum();
        udpPacket.Checksum = (ushort)sum1;
        ushort sum2 = ipPacket.CalculateIPChecksum();
        ipPacket.Checksum = sum2;

        //创建链路层数据包
        var sourceHwAddress = "A4BC6DB92C05";
        var ethernetSourceHwAddress = System.Net.NetworkInformation.PhysicalAddress.Parse(sourceHwAddress);
        var ethernetDestinationHwAddress = System.Net.NetworkInformation.PhysicalAddress.Parse(sourceMac);
        var ethernetPacket = new EthernetPacket(ethernetSourceHwAddress, ethernetDestinationHwAddress, EthernetPacketType.None);

        //数组负载数据
        ethernetPacket.PayloadPacket = ipPacket;
        byte[] packetBytes = ethernetPacket.Bytes;

        //发送sharPcap的udp命令
        _device.SendPacket(packetBytes);
    }



    public void StopAll()
    {
        if (_device != null && _device.Opened)
        {
            Thread.Sleep(500);
            _device.StopCapture();
        }
        _thread.Abort();
        _thread = null;
        _device = null;
    }

    public bool SharPcapConnect()
    {
        if (_device == null || !_device.Opened)
        {
            getNetWorkInfo(Globel._Network.IP);
            return Listen();
        }
        else return true;
    }
}

}

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 3月8日
    • 创建了问题 2月28日

    悬赏问题

    • ¥15 QT任务管理器无法正确获取展开,有悬赏15元速求,如何解决?(相关搜索:标识符|结构体)
    • ¥15 使用delphi 10.3+intraweb 生成的页面怎么实现自动滚屏
    • ¥20 思科:Router c3600 MN-4E插槽
    • ¥15 16进制修改视频的元数据
    • ¥15 HTML中css的位置信息居然会导致元素大小发生变化
    • ¥15 岛津txt格式文件转nirs格式
    • ¥15 石墨烯磁表面等离子体
    • ¥15 angular 项目无法启动
    • ¥15 安装wampserver,图标绿色,但是无法进入软件
    • ¥15 C++ MFC 标准库 加密解密解惑