首页 > 解决方案 > c# Packet Sniffer - 嗅探器丢失数据包是否正常?

问题描述

我使用原始套接字创建了 ac# 数据包嗅探器。我注意到,当我从客户端 TCP 程序向服务器 TCP 程序发送一些消息时,并将这些消息编号为例如 1 到 50。

服务器 TCP 程序接收所有消息 1 到 50,但侦听此 ip 的嗅探器仅获取随机消息,例如 5,然后是 7,8 等等...

这对于 c# 中的原始套接字嗅探器是否正常?这是c#中Raw Socket的限制吗?我需要去一个更底层的框架,比如pCap等吗?

提前致谢!

代码(显示了所有关键部分,排除了解析数据包的库,它类似于那里的代码项目:

因此,下面的代码显示了从按下开始按钮到处理在特定 IP 地址上被嗅探的数据包所采取的步骤。我能够嗅探数据,但正如我所说,当我尝试使用 TCP 客户端和服务器时,我无法嗅出 TCP 客户端和服务器应用程序之间发送和接收的所有消息,只有其中一些被已接。假设我在客户端和服务器 TCP 应用程序之间触发 1 到 50 条消息。TCP 服务器和客户端将它们全部拾起,但侦听同一 IP 地址的嗅探器仅拾取一些消息,例如 1、5、6、10 等……它有差距。同样,这对于嗅探器应用程序是否正常,还是应该获取与 TCP 客户端和服务器应用程序获取的所有相同的流量?

    private const int p_PacketBufferSize = 65536; // this is the Maximum size that a packet will ever be
    private byte[] p_PacketBuffer = new byte[p_PacketBufferSize]; //Packet Buffer

    private void btnStart_Click(object sender, EventArgs e)
    {
        if (btnStart.Text.ToLower() == "start")
        {
            btnStart.Text = "Stop";

            //set ip address to bind outside of async task begin
            string interfaceName = lstAdapters.SelectedValue.ToString();
            string ipVal = lstIpAddress.SelectedValue.ToString();
            Task.Run(async () =>
            {
                bool status = await StartListening(ipVal, interfaceName);
                return status;
            });
        }
        else
        {
            btnStart.Text = "Start";
            adp.StopTraffic();
        }
    }

    private Task<bool> StartListening(string ipVal, string interfaceName)
    {
        try
        {
            IPHostEntry ipHost = Dns.GetHostEntry(ipVal);
            string domainName = ipVal;
            if (!string.IsNullOrEmpty(ipHost.HostName))
            {
                domainName = ipHost.HostName;
            }
            SetText(null, "============================================================================================================\r\n"
                    + "INTERFACE: (" + interfaceName + ") - IP ADDRESS: (" + ipVal + ") - DOMAIN NAME: (" + domainName + ")\r\n"
                    + "============================================================================================================\r\n");

            //process monitoring
            adp.MonitorTraffic(ipVal, packetRecEvent);
        }
        catch (Exception ex)
        {
            Logging.Add("Error Initializing IP Monitoring: " + ex.Message + " (" + ipVal + ")");
            MessageBox.Show("Error Occurred: " + ex.Message + " (" + ipVal + ")");
        }

        return Task.FromResult(true);
    }


    public void MonitorTraffic(string ipVal, PacketReceiveEvent pkRecEv)
    {
        //set continue capturing traffic flag
        bContinueCapturing = true;
        packetRecEvent = pkRecEv;
        try
        {
            //initialize a new socket
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
            socket.Bind(new IPEndPoint(IPAddress.Parse(ipVal), 0));
            socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);

            byte[] byTrue = new byte[4] { 1, 0, 0, 0 };
            byte[] byOut = new byte[4] { 1, 0, 0, 0 };
            socket.IOControl(IOControlCode.ReceiveAll, byTrue, byOut);
            while (bContinueCapturing)
            {
                socket.BeginReceive(p_PacketBuffer, 0, p_PacketBufferSize, SocketFlags.None, new AsyncCallback(OnReceive), null);
                while (socket.Available == 0)
                {
                    Thread.Sleep(1);
                }
            }
        }
        catch (Exception ex)
        {
            Logging.Add("ERROR: on topmost level starting server listener: " + ex.Message);
        }
        finally
        {
            if (socket != null)
            {
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
            }
        }
    }

    private void OnReceive(IAsyncResult ar)
    {
        try
        {
            instanceCounterThread++;
            //read the data from client socket
            int bytesRead = socket.EndReceive(ar);
            if (bytesRead > 0)
            {
                //clear the array from current state object
                PacketHandler pkHandler = new PacketHandler(packetRecEvent, p_PacketBuffer, bytesRead);
                //p_PacketBuffer = new byte[p_PacketBufferSize];
            }

            instanceCounterThread--;
            //Logging.Add("DEBUG: " + instanceCounterThread.ToString());
            if ((instanceCounterThread == 0) && (!bContinueCapturing))
            {
                packetRecEvent.fire(null, "============================================================================================================\r\n\r\n");
            }
        }
        catch (Exception ex)
        {
            if (ex.Message.ToLower().IndexOf("disposed") < 0)
            {
                Logging.Add("INFO Socket Error: " + ex.Message);
                //MessageBox.Show("Error: " + ex.Message);
            }
        }
    }

标签: socketsnetworkingipsniffer

解决方案


我已经解决了这个问题。这是我管理传入缓冲区数据和管理每个进程的线程的方式的线程问题。

谢谢。


推荐阅读