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