c#Packet Sniffer-嗅探器丢失数据包是否正常?

时间:2019-05-13 22:33:02

标签: sockets networking ip sniffer

我已经使用Raw Sockets创建了一个c#数据包嗅探器。我注意到,当我从客户端TCP程序向服务器TCP程序发送一些消息时,将这些消息编号为1到50。

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

C#中的原始套接字嗅探器正常吗?这是c#中Raw套接字的限制吗,我是否需要使用pCap等更底层的框架??

提前谢谢!

CODE(显示了所有关键部分,但不包括用于解析数据包的库,该库类似于那里的代码项目:

因此下面的代码显示了从按下开始按钮到处理在特定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);
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

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

谢谢。