关于c#实现影音嗅探的问题

原创 2007年11月21日 23:08:00
这几天参考网上的RawSocket初步些了个,但发现丢包现象严重,效果很不理想很多时候都嗅探不出来
后来借助httpwatch的API接口页很理想,大家有什么关于.net上的实现思虑么? vb.net或c#都行 


下面这个基类是我仿照网上些的
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Net.Sockets;
using System.Net;

namespace v.sniffer
{
    /**
     * IP数据包结构,解释完毕的包存放到这里,最终用它来组成总的数据
     */
    [StructLayout(LayoutKind.Explicit)]
    public struct IPHeader
    {
        [FieldOffset(0)]
        public byte ip_verlen;        //I4位首部长度+4位IP版本号
        [FieldOffset(1)]
        public byte ip_tos;            //8位服务类型TOS
        [FieldOffset(2)]
        public ushort ip_totallength; //16位数据包总长度(字节)
        [FieldOffset(4)]
        public ushort ip_id;             //16位标识
        [FieldOffset(6)]
        public ushort ip_offset;       //3位标志位
        [FieldOffset(8)]
        public byte ip_ttl;            //8位生存时间 TTL
        [FieldOffset(9)]
        public byte ip_protocol;    //8位协议(TCP, UDP, ICMP, Etc.)
        [FieldOffset(10)]
        public ushort ip_checksum; //16位IP首部校验和
        [FieldOffset(12)]
        public uint ip_srcaddr;     //32位源IP地址
        [FieldOffset(16)]
        public uint ip_destaddr;   //32位目的IP地址
    }

    public class RawSocket
    {
        private bool error_occurred;          //套接字在接收包时是否产生错误
        public bool KeepRunning;              //是否继续进行
        private int len_receive_buf;       //得到的数据流的长度
        byte[] receive_buf_bytes;          //收到的字节
        private Socket socket = null;       //声明套接字
        const int SIO_RCVALL = unchecked((int)0x98000001);//监听所有的数据包

        /**
         * 构造函数
         */
        public RawSocket()
        {
            error_occurred = false;//没有产生错误
            len_receive_buf = 4096;//接收的数据流的长度
            receive_buf_bytes = new byte[len_receive_buf];//接收的内容
        }

        /**
         * 建立并绑定套接字
         *
         * @param 要监听的IP地址,单网卡的可以直接通过Dns.GetHostByName(Dns.GetHostEntry()).AddressList[0].ToString()方式来指定监听本地
         */
        public void CreateAndBindSocket(string IP)
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
            socket.Blocking = false;                                         //设置socket非阻塞状态
            socket.Bind(new IPEndPoint(IPAddress.Parse(IP), 0)); //绑定套接字

            if (SetSocketOption() == false) error_occurred = true;//开始侦听数据
        }

        /**
         * 侦听数据包的参数
         */
        private bool SetSocketOption()                           //设置raw socket
        {
            bool ret_value = true;
            try
            {
                socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, 1);
                byte[] IN = new byte[4] { 1, 0, 0, 0 };
                byte[] OUT = new byte[4];

                //低级别操作模式,接受所有的数据包,这一步是关键,必须把socket设成raw和IP Level才可用SIO_RCVALL
                int ret_code = socket.IOControl(SIO_RCVALL, IN, OUT);
                ret_code = OUT[0] + OUT[1] + OUT[2] + OUT[3];//把4个8位字节合成一个32位整数
                if (ret_code != 0) ret_value = false;
            }
            catch (SocketException)
            {
                ret_value = false;
            }
            return ret_value;
        }

        public bool ErrorOccurred
        {
            get
            {
                return error_occurred;
            }
        }
        //解析接收的数据包,形成PacketArrivedEventArgs事件数据类对象,并引发PacketArrival事件
        unsafe private void Receive(byte[] buf, int len)
        {
            byte temp_protocol = 0;//协议
            uint temp_version = 0;//版本
            uint temp_ip_srcaddr = 0;//源地址
            uint temp_ip_destaddr = 0;//目的地址
            short temp_srcport = 0;//源端口
            short temp_dstport = 0;//目标端口
            IPAddress temp_ip;//IP地址

            PacketArrivedEventArgs e = new PacketArrivedEventArgs();//新网络数据包信息事件

            fixed (byte* fixed_buf = buf)
            {
                IPHeader* head = (IPHeader*)fixed_buf;//把数据流整和为IPHeader结构
                e.HeaderLength = (uint)(head->ip_verlen & 0x0F) << 2;
                e.IPHeaderBuffer = new byte[e.HeaderLength];

                temp_protocol = head->ip_protocol;
                switch (temp_protocol)//提取协议类型
                {
                    case 1: e.Protocol = "ICMP"; break;
                    case 2: e.Protocol = "IGMP"; break;
                    case 6: e.Protocol = "TCP"; break;
                    case 17: e.Protocol = "UDP"; break;
                    default: e.Protocol = "UNKNOWN"; break;
                }

                temp_version = (uint)(head->ip_verlen & 0xF0) >> 4;//提取IP协议版本
                e.IPVersion = temp_version.ToString();

                //以下语句提取出了PacketArrivedEventArgs对象中的其他参数
                temp_ip_srcaddr = head->ip_srcaddr;
                temp_ip_destaddr = head->ip_destaddr;
                temp_ip = new IPAddress(temp_ip_srcaddr);
                e.OriginationAddress = temp_ip.ToString();
                temp_ip = new IPAddress(temp_ip_destaddr);
                e.DestinationAddress = temp_ip.ToString();

                temp_srcport = *(short*)&fixed_buf[e.HeaderLength];
                temp_dstport = *(short*)&fixed_buf[e.HeaderLength + 2];
                e.OriginationPort = IPAddress.NetworkToHostOrder(temp_srcport).ToString();
                e.DestinationPort = IPAddress.NetworkToHostOrder(temp_dstport).ToString();

                e.PacketLength = (uint)len;
                e.MessageLength = (uint)len - e.HeaderLength;
                e.MessageBuffer = new byte[e.MessageLength];

                e.ReceiveBuffer = buf;
                //把buf中的IP头赋给PacketArrivedEventArgs中的IPHeaderBuffer
                Array.Copy(buf, 0, e.IPHeaderBuffer, 0, (int)e.HeaderLength);
                //把buf中的包中内容赋给PacketArrivedEventArgs中的MessageBuffer
                Array.Copy(buf, (int)e.HeaderLength, e.MessageBuffer, 0, (int)e.MessageLength);
            }
            //引发PacketArrival事件
            OnPacketArrival(e);
        }
        public void Run() //开始监听
        {
            if (socket != null)
            {
                IAsyncResult ar = socket.BeginReceive(receive_buf_bytes, 0, len_receive_buf, SocketFlags.None, new AsyncCallback(CallReceive), this);
            }
        }
        private void CallReceive(IAsyncResult ar)//异步回调
        {
            if (socket != null)
            {
                try
                {
                    int received_bytes;
                    received_bytes = socket.EndReceive(ar);
                    Receive(receive_buf_bytes, received_bytes);
                    if (KeepRunning) Run();
                }catch (Exception e) { }
            }
        }

        public void Shutdown()                                       //关闭raw socket
        {
            if (socket != null)
            {
                try
                {
                    socket.Shutdown(SocketShutdown.Both);
                    socket.Close();
                    socket = null;
                }catch (Exception e) { }
            }
        }

        public delegate void PacketArrivedEventHandler(Object sender, PacketArrivedEventArgs args);
        //事件句柄:包到达时引发事件
        public event PacketArrivedEventHandler PacketArrival;//声明时间句柄函数
        private void OnPacketArrival(PacketArrivedEventArgs e)
        {
            PacketArrivedEventHandler temp = PacketArrival;
            if (temp != null)
                temp(this, e);
        }

        public class PacketArrivedEventArgs : EventArgs
        {
            public uint HeaderLength;
            public string Protocol;
            public string IPVersion;
            public string OriginationAddress;
            public string DestinationAddress;
            public string OriginationPort;
            public string DestinationPort;
            public uint PacketLength;
            public uint MessageLength;
            public byte[] ReceiveBuffer;
            public byte[] IPHeaderBuffer;
            public byte[] MessageBuffer;
            public PacketArrivedEventArgs()
            {
            }
            public override string ToString()
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("/r/n----------------/r/n");
                sb.AppendFormat("src = {0}:{1}, dst= {2}:{3}/r/n", OriginationAddress, OriginationPort,
                    DestinationAddress, DestinationPort);
                sb.AppendFormat("protocol = {0}, ipVersion={1}/r/n", Protocol, IPVersion);
                sb.AppendFormat("PacketLength={0},MessageLength={1}", PacketLength, MessageLength);
                sb.Append("/r/n----------------/r/n");
                return sb.ToString();
            }
        }

    }
}



这个是我的主窗口调用


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using v.sniffer;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Collections;

namespace v.winForms
{
    public partial class listen : Form
    {
        private Hashtable ht = new Hashtable();
        private System.Data.DataTable httpTable =new DataTable("httpList");
        private RawSocket socket = null;
        delegate void mydelegate();//表单子线程代理   
        public listen()
        {
            InitializeComponent();
        }


        private void btn_browser_Click(object sender, EventArgs e)
        {
            if (!this.btn_ListenStart.Enabled)
            {
                this.startRequest();
            }
            else
            {
                MessageBox.Show("请先打开监听,在开始请求");
            }
        }

        private void startRequest()
        {
            if (!listenUrl.Text.Equals(""))
            {
                v.winForms.easyBrowser eBrowser = new easyBrowser();
                eBrowser.openUrl(listenUrl.Text);
                if (chkDebugMode.Checked)
                {
                    eBrowser.Show();
                }

            }
        }

        private void btn_ListenStart_Click(object sender, EventArgs e)
        {
            this.listenList.Invoke(new mydelegate(ListenThread));//初始化合同服务分类
            this.btn_ListenStart.Enabled = false;
            this.btn_ListenStop.Enabled = true;
        }

        private void btn_ListenStop_Click(object sender, EventArgs e)
        {
            this.listenList.Invoke(new mydelegate(ListenStop));//初始化合同服务分类
            this.btn_ListenStart.Enabled = true;
            this.btn_ListenStop.Enabled = false;
        }

        private void ListenStop()
        {
            if (this.socket != null)
            {
                this.socket.Shutdown();
            }
        }


        /**
        * 侦听线程
        */
        public void ListenThread()
        {
            try
            {
                socket = new RawSocket();
                IPAddress hosts = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
                socket.CreateAndBindSocket(hosts.ToString());
                if (socket.ErrorOccurred)
                {
                    MessageBox.Show("侦听出错了");
                    return;
                }
                socket.KeepRunning = true;
                socket.PacketArrival += socket_PacketArrival;
                socket.Run();
                this.startRequest();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                throw;
            }
            finally
            {
              
            }
        }

        private void appendRow(string strUrl,string strContentType)
        {
            string[] arrSubItem = new string[2];
            arrSubItem[0] = strUrl;
            arrSubItem[1] = strContentType;
            ListViewItem LiItem = new ListViewItem(arrSubItem, 0);
            LiItem.Tag = "这里可以存储额外的信息";
            this.listenList.Items.Add(LiItem);
        }


        private string byte2str(byte[] barr)
        {
            return Encoding.UTF8.GetString(barr).Trim();
            /*
             *System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding();
                string strRequest = converter.GetString(httpData).Trim();
                //string strRequest = Encoding.ASCII.GetString(httpData).Trim();//UTF8
             */
        }
        void socket_PacketArrival(object sender, RawSocket.PacketArrivedEventArgs args)
        {

        [color=#FF0000]    string localIp = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0].ToString();
            if (args.Protocol == "TCP" && args.OriginationAddress == localIp) // && (args.OriginationAddress == localIp || args.DestinationAddress == localIp)
            {
                byte[] httpData = new byte[args.MessageLength];
                Buffer.BlockCopy(args.MessageBuffer, 0, httpData, 0, httpData.Length);
                string strRequest = Encoding.UTF8.GetString(httpData).Trim();
              
                v.sniffer.headerSplit hSplit = new v.sniffer.headerSplit();
                hSplit.setHeader(strRequest);
                string strHost = hSplit.getHost();
                string strPath = hSplit.getPath();
                string strPort = args.DestinationPort;
                string strContentType = hSplit.getContentType();
                if (strPort.Equals("80"))
                {
                    strPort = "";
                }
                else
                {
                    strPort = ":" + strPort;
                }

                //if (!strHost.Equals(""))
                {
                    string strUrl = "http://" + strHost + strPort + strPath;
                    string strKey = args.OriginationPort + args.DestinationAddress + args.DestinationPort;

                    MessageBox.Show(strUrl);
                    if (ht.Contains(strKey))
                    {
                        ht[strKey] = strUrl;
                    }
                    else
                    {
                        ht.Add(strKey, strUrl);
                    }

                }

                if (!strContentType.Equals(""))
                {
                    string strKey = args.DestinationPort + args.OriginationAddress + args.OriginationPort;
                    string strUrl = "";
                    if (ht.Contains(strKey))
                    {
                        strUrl = ht[strKey].ToString();
                        ht.Remove(strKey);
                    }

                    bool isCheckType=(this.chk_listenType.Checked == false && strContentType.Contains("video/x-flv")||(this.chk_listenType.Checked == true));
                    if(!strUrl.Equals(""))
                    {
                        if (isCheckType)
                        {
                            this.appendRow(strUrl, strContentType);              
                        }
                        DataRow dataRow = httpTable.NewRow();
                        dataRow["url"] = strUrl;
                        dataRow["type"] = strContentType;
                        httpTable.Rows.Add(dataRow);
                    }[/color]
                }
              

            }
        }

        private void listen_Load(object sender, EventArgs e)
        {
            httpTable.Columns.Add("url", Type.GetType("System.String"));
            httpTable.Columns.Add("type", Type.GetType("System.String"));
            /*
            System.Windows.Forms.ColumnHeader urlColumn = new System.Windows.Forms.ColumnHeader();
            urlColumn.Text = "URL地址";
            urlColumn.Width = 500;
            this.listenList.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { urlColumn });
             */
        }

        private void btn_listClear_Click(object sender, EventArgs e)
        {
            this.listenList.Items.Clear();
            httpTable.Rows.Clear();
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            this.listenList.Items.Clear();
            for (int i = 0; i < httpTable.Rows.Count; i++)
            {
                bool isCheckType = (this.chk_listenType.Checked == false && httpTable.Rows[i]["type"].ToString().Contains("video/x-flv") || (this.chk_listenType.Checked == true));
                if (!httpTable.Rows[i]["url"].Equals(""))
                {
                    if (isCheckType)
                    {
                        string[] arrSubItem = new string[2];
                        arrSubItem[0] = httpTable.Rows[i]["url"].ToString();
                        arrSubItem[1] = httpTable.Rows[i]["type"].ToString();
                        ListViewItem LiItem = new ListViewItem(arrSubItem, 0);
                        LiItem.Tag = "这里可以存储额外的信息";
                        this.listenList.Items.Add(LiItem);
                    }
                }
            }
        }

        private void 打开ToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }



    }
}


这个是分析http头用的

using System;
using System.Collections.Generic;
using System.Text;

namespace v.sniffer
{
    class headerSplit
    {
        private string[] Arrheader;
        public void setHeader(string strHeader)
        {
            this.Arrheader = strHeader.Split("/r/n/r/n".ToCharArray());
        }
        public string getPath()
        {
            string strPath = "";
            for (int i = 0; i < this.Arrheader.Length; i++)
            {
                bool matchPath = new System.Text.RegularExpressions.Regex("GET /.+ HTTP/").IsMatch(this.Arrheader[i].ToUpper()); // 在字符串中匹配
                if (matchPath)
                {
                    string[] tmp = this.Arrheader[i].Split(" ".ToCharArray());
                    for (int j = 0; j < tmp.Length; j++)
                    {
                        bool matchGet = new System.Text.RegularExpressions.Regex("GET").IsMatch(tmp[j].ToUpper());
                        int next = j + 1;
                        if (matchGet && next < tmp.Length)
                        {
                            strPath = tmp[next].Trim();
                            break;
                        }
                    }
                }
                if (!strPath.Equals(""))
                {
                    break;
                }
            }
            return strPath;
        }
        public string getHost()
        {
            string strHost = "";
            for (int i = 0; i < this.Arrheader.Length; i++)
            {
                bool matchHost = new System.Text.RegularExpressions.Regex("HOST: ").IsMatch(this.Arrheader[i].ToUpper()); // 在字符串中匹配
                if (matchHost)
                {
                    string[] tmp = this.Arrheader[i].Split(" ".ToCharArray());
                    for (int j = 0; j < tmp.Length; j++)
                    {
                        bool matchGet = new System.Text.RegularExpressions.Regex("HOST:").IsMatch(tmp[j].ToUpper());
                        int next = j + 1;
                        if (matchGet && next < tmp.Length)
                        {
                            strHost = tmp[next].Trim();
                            break;
                        }
                    }
                }
                if (!strHost.Equals(""))
                {
                    break;
                }
            }
            return strHost;
        }

        public string getContentType()
        {
            string strReturn = "";
            for (int i = 0; i < this.Arrheader.Length; i++)
            {
                bool boomatch = new System.Text.RegularExpressions.Regex("CONTENT-TYPE: ").IsMatch(this.Arrheader[i].ToUpper()); // 在字符串中匹配
                if (boomatch)
                {
                    string[] tmp = this.Arrheader[i].Split(" ".ToCharArray());
                    for (int j = 0; j < tmp.Length; j++)
                    {
                        bool matchGet = new System.Text.RegularExpressions.Regex("CONTENT-TYPE:").IsMatch(tmp[j].ToUpper());
                        int next = j + 1;
                        if (matchGet && next < tmp.Length)
                        {
                            strReturn = tmp[next].Trim();
                            break;
                        }
                    }
                }
                if (!strReturn.Equals(""))
                {
                    break;
                }
            }
            return strReturn;
        }
    }
}


这个是调用IE的插件

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace v.winForms
{
    public partial class easyBrowser : Form
    {
        public easyBrowser()
        {
            InitializeComponent();
        }

        private void easyBrowser_Load(object sender, EventArgs e)
        {
            //objBrowser.Navigate(txt_url.Text);
        }

        private void btn_go_Click(object sender, EventArgs e)
        {
            objBrowser.Navigate(txt_url.Text);
        }

        public void openUrl(string url)
        {
            txt_url.Text = url;
            objBrowser.Navigate(url);
        }
        private void objBrowser_DownloadComplete(object sender, EventArgs e)
        {

        }

        private void objBrowser_DocumentComplete(object sender, AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e)
        {

        }

    }
}

 

在c#用raw socket进行sniff嗅探(一)

raw socket 三部曲:socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);sock...
  • f_jy
  • f_jy
  • 2007年02月12日 01:58
  • 4402

点量视频网站真实视频地址解析嗅探BT组件内核

  • 2011年05月16日 17:20
  • 477KB
  • 下载

基于C#实现的嗅探器

  • 2016年08月18日 16:38
  • 54KB
  • 下载

如何下载流媒体

如何下载流媒体  随着Internet技术的快速发展,流媒体技术(点这里查看什么是流媒体)的应用也越来越普及,如今在线观看电影或收听广播(这类节目称作“流媒体”节目)已成为时尚。有的朋友很想把喜欢的节...
  • lanyd
  • lanyd
  • 2009年07月21日 18:44
  • 1669

转载--memcached缓存服务器的安装

一、memcached 的编译安装 准备: Memcached下载地址:http://www.danga.com/memcached/ libevent下载地址: http://monkey.org/...
  • muyannian
  • muyannian
  • 2007年11月05日 15:14
  • 1932

关于c#实现影音嗅探的问题(转)

 这几天参考网上的RawSocket初步些了个,但发现丢包现象严重,效果很不理想很多时候都嗅探不出来后来借助httpwatch的API接口页很理想,大家有什么关于.net上的实现思虑么? vb.net...
  • cuoban
  • cuoban
  • 2009年05月05日 15:57
  • 394

如何找到一首歌的真实下载地址!

如何找到一首歌的真实下载地址!在网上当你听到一首首动听的音乐时,你会不会有一种想把他下下来的冲动?可好多网站都设置了种种限制,不让我们称心如意的下载。下...
  • kof820
  • kof820
  • 2006年05月09日 00:34
  • 3748

QQ影音截取功能

QQ影音截取视频或音频:   第一步:选取“工具”中的“截取”功能   第二步:如下图中的“微调”按钮:可以轻微调节所需视频或音频片段 第三步:如下图“预览”按钮:可以预览所选择的视频或音频片段,...
  • hanxuemin12345
  • hanxuemin12345
  • 2012年04月01日 21:56
  • 1629

SQL Server 查询优化(测试02)参数嗅探-执行计划选择

最近常看到"参数嗅探"这个词,看了几篇文章,于是就自己摸索做个测试来加深印象! 去官网下载了数据库:AdventureWorks2012 直接测试吧! 找几个熟悉的表关联起来,用ProductI...
  • kk185800961
  • kk185800961
  • 2014年12月28日 03:09
  • 2642

Java实现简单的个人网络嗅探器

jpcap
  • qq_34838643
  • qq_34838643
  • 2017年12月25日 11:57
  • 329
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于c#实现影音嗅探的问题
举报原因:
原因补充:

(最多只允许输入30个字)