[搜片神器]使用C#實現DHT磁力搜索的BT種子後端管理程序+數據庫設計(開源)

謝謝園子朋友的支持,已經找到個VPS進行測試,國外的服務器:http://www.sosobta.com   你們能夠給提點意見...git

先直接上程序界面,瞭解總體工做流程是什麼樣子的,求服務器進行掛機測試,須要固定IP,空間大概須要10G左右(主要是BT種子佔用空間過大),最好有SQLSERVER來作爲存儲數據庫,目前採用的是ACCESS數據庫作爲測試,怕後期數據過百萬,對網站進行查詢操做很慢。github

若是程序運行的時間夠長,基本上網絡上的種子都會過來,至關於搜片神器了.正則表達式

開源地址:https://github.com/h31h31/H31DHTMgr數據庫

程序下載:H31DHT下載服務器

也提供ASP網站的訪問模式:網絡

 

正在運行中的狀態:app

本次主要介紹對DHT磁力搜索的HASH文件進行處理操做流程。測試

後臺處理程序主要採用C#裏面讀取文件類來進行讀取,目前文件格式分爲兩種,一種是從http://torrage.com/sync下載回來的文件進行處理,網站

另一種是採用C++程序對DHT網絡中的HASH文件進行搜索存儲的自定義文件,url

裏面有HASH值和時間IP等信息,能夠經過這些IP值分析出對方電腦上有哪些BT文件,固然這裏面的HASH值對應的文件對應的但是當前活躍在網絡上的文件,與上面網站上下載的固定的文件值有區別,

有了這些IP值,我的也能夠作些行爲分析方面的工做,好比哪些城市的IP在下載些什麼類型的文件。

 

下面介紹下數據庫方面的設計工做:

1.初步考慮到SQLSERVER對本身電腦工做速度會有影響,沒有安裝SQLSERVER數據庫,採用ACCESS來進行處理操做;

2.ACCESS數據庫每一個表的大小最好控制不要超過4G,因此設計每表不超過100百萬條數據;

3.對BT種子文件進行解析後,提取裏面的文件名字,按照文件類型存儲到不一樣的表中,主要分爲6大類,電影,音樂,圖片,書箱,程序,其它類,

4.因爲BT種子裏面語言對應的不同,有中文,英文,日文,韓國等語言,對於搜索界面若是所有存儲到一塊,沒有什麼問題,但會影響查詢速度,由於中國人通常喜歡用中文查詢,若是想查日文,對選項進行選擇一下,這樣會對全部的表查詢都會有很大提升,由於每一個表的文件都基本上針對幾種語言;

5.對於BT種子裏面的文件列表直接採用100百萬一個表,若是超過了,直接存儲第二塊表,由於主表裏面有存儲本身的文件列表在哪一個表的關鍵字段;

6.另外對數據庫信息也比較嚴謹一些,因爲種子文件裏面有不少廣告信息,好比視頻種子裏面常常有網站URL,TXT,MHT等信息連接,程序通過初步判斷直接不存儲到文件表數據庫中,佔用數據庫空間,影響查詢速度,另外查詢出來顯示列表也很差看.

7.對於一個種子裏面常常有>200多個的種子文件也沒有進行存儲,一個種子有不少文件也比較浪費空間,再說這種種子保存下來基本上都沒什麼意義,直接PASS;

8.對於文件名裏面有網站信息的也採起的過濾措施,對查詢有很好幫助.

數據庫表設計列表:

存儲DHT文件名字的表:

存儲種子文件列表:

 

--------------------------下面先介紹一下DHT的工做原理--------------------------------

DHT網絡本質上是一個用於查詢的網絡,其用於查詢一個資源有哪些計算機正在下載。每一個資源都有一個20字節長度的ID用於標示,稱爲infohash。當一個程序做爲DHT節點加入這個網絡時,就會有其餘節點來向你查詢,當你作出迴應後,對方就會記錄下你。對方還會詢問其餘節點,當對方開始下載這個infohash對應的資源時,他就會告訴全部曾經詢問過的節點,包括你。這個時候就能夠肯定,這個infohash對應的資源在這個網絡中是有效的。

關於這個網絡的工做原理,參看Kevin寫的:P2P中DHT網絡爬蟲以及寫了個磁力搜索的網頁

獲取到infohash後能作什麼?關鍵點在於,咱們如今使用的磁力連接(magnet url),是和infohash對應起來的。也就是拿到infohash,就等於拿到一個磁力連接。可是這個爬蟲還須要創建資源的信息,這些信息來源於種子文件。種子文件其實也是對應到一個資源,種子文件包含資源名、描述、文件列表、文件大小等信息。獲取到infohash時,其實也獲取到了對應的計算機地址,咱們能夠在這些計算機上下載到對應的種子文件。

在獲取到infohash後,從一些提供映射磁力鏈到種子文件服務的網站上直接下載了對應的種子。

http://torrage.com
https://zoink.it
http://bt.box.n0808.com

-------------------------咱們後臺處理程序就從上面進行種子的下載工做---------------------------

下面重點介紹下咱們程序的模塊設計:

1.H31SQL類主要方面進行ACCESS和SQLSERVER數據庫操做進行初步封裝的一個類;

2.H31Debug主要是日誌輸出類

3.H31Down主要是下載BT種子文件進行的類;

4.TorrentFile類是用來解析BT種子文件類,因爲目前可能有的BT種子格式對不上,有些文件解析不上;

5. MainForm主程序界面。

------------------------------------

下面介紹程序處理數據的主要流程:

 1.讀取本地文件,採用正則表達式對數據進行提取

        /// <summary>
        /// 正則表達式取出內容 2013-07-16
        /// </summary>
        private int GetHashLineContent(string hashline, ref HASHITEM item1)
        {
            if (hashline.Length < 50)
            {
                if (hashline.Length == 40)
                {
                    item1.hashKey = hashline.Trim();
                    item1.recvTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    item1.recvIp = "127.0.0.1";
                    item1.recvPort = 8080;
                    return 1;
                }
                else
                {
                    int a = 0;
                }
            }
            else
            {
                string pattern = @"ash\[(.*)\] Time\#(.*)\# ip\:(.*)\:(.*)\.";
                Match usermatch = Regex.Match(hashline, pattern, RegexOptions.IgnoreCase);
                if (usermatch.Groups.Count == 0)
                {
                    pattern = @"ash\[(.*)\] Time\#(.*)\# ip\:(.*)\:(.*)\.(.*)\#";
                    usermatch = Regex.Match(hashline, pattern, RegexOptions.IgnoreCase);
                }

                if (usermatch.Groups.Count >= 4 && recvthreadison)
                {
                    item1.hashKey = usermatch.Groups[1].Value.ToString();
                    item1.recvTime = Convert.ToDateTime(usermatch.Groups[2].Value.ToString());
                    item1.recvIp = usermatch.Groups[3].Value.ToString();
                    item1.recvPort = Convert.ToInt32(usermatch.Groups[4].Value.ToString());
                    return 1;
                }
            }
            return 0;

        }

  2.從網站下載BT種子文件來進行處理

        private int DownLoadFileToSaveFile(string strURL, string fileName,int timeout1)
        {
            Int32 ticktime1 = System.Environment.TickCount;
            try
            {
                Int32 ticktime2 = 0;
                byte[] buffer = new byte[4096];

                WebRequest wr = WebRequest.Create(strURL);
                wr.ContentType = "application/x-bittorrent";
                wr.Timeout = timeout1;
                WebResponse response = wr.GetResponse();
                int readsize = 0;
                {
                    bool gzip = response.Headers["Content-Encoding"] == "gzip";
                    Stream responseStream = gzip ? new GZipStream(response.GetResponseStream(), CompressionMode.Decompress) : response.GetResponseStream();

                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        responseStream.ReadTimeout = timeout1*2;
                        int count = 0;
                        do
                        {
                            count = responseStream.Read(buffer, 0, buffer.Length);
                            memoryStream.Write(buffer, 0, count);
                            readsize += count;
                            Thread.Sleep(1);
                        } while (count != 0);
                        ticktime2 = System.Environment.TickCount;

                        byte[] result = memoryStream.ToArray();
                        Thread.Sleep(10);
                        using (BinaryWriter writer = new BinaryWriter(new FileStream(fileName, FileMode.Create)))
                        {
                            writer.Write(result);
                        }
                    }
                    Int32 ticktime3 = System.Environment.TickCount;
                    //H31Debug.PrintLn("下載成功" + strURL + ":" + readsize.ToString() + ":" + (ticktime2 - ticktime1).ToString() + "-" + (ticktime3 - ticktime2).ToString());
                }
                return 1;
            }
            catch (Exception e)
            {
                Int32 ticktime3 = System.Environment.TickCount;
                //H31Debug.PrintLn("下載失敗" + strURL + ":" +  (ticktime3 - ticktime1).ToString());
                return -2;
            }
        }

3.經過BT文件解析類來讀取文件名和列表

4.經過正確正則表達式過濾掉WWW. BBS. 等網站信息,由於這樣會影響搜索結果.

        /// <summary>
        /// 去掉標題中的網址信息
        /// </summary>
        private string GetOneGoodString(string title)
        {
            //去掉標題中的網址信息
            string res = title;
            try
            {
                //string pattern = @"\[(.*)([\w-]+://?|(www|bbs)[.])([^\]]*)\]";
                string pattern = @"(\[|\@|\【|\s|\(|\{)(.*)([\w-]+://?|(www|bbs)[.])([^(\]|\@|\】|\)|\})]*)(\]|\@|\】|\)|\})";
                Match usermatch = Regex.Match(title, pattern, RegexOptions.IgnoreCase);
                if (usermatch.Groups.Count > 1)
                {
                    res = res.Replace(usermatch.Groups[0].Value.ToString(), " ");
                    res = res.Trim();
                }
                pattern = @"(\[|\@|\【|\s|\(|\{)(.*)\.(com|edu|gov|mil|net|org|biz|info|name|museum|us|ca|uk|cc|me|cm)([^(\]|\@|\】|\)|\}|\s)]*)(\]|\@|\】|\)|\}|\s)";
                //pattern = @"(\[|\@|\【)(.*)([\w-]+://?|(www|bbs)[.])([^(\]|\@|\】)]*)(\]|\@|\】)";
                usermatch = Regex.Match(res, pattern, RegexOptions.IgnoreCase);
                if (usermatch.Groups.Count > 1)
                {
                    res = res.Replace(usermatch.Groups[0].Value.ToString(), " ");
                    res = res.Trim();
                }
                pattern = @"(www|bbs)(.*)(com|edu|gov|mil|net|org|biz|info|name|museum|us|ca|uk|cc|me|cm)";
                usermatch = Regex.Match(res, pattern, RegexOptions.IgnoreCase);
                if (usermatch.Groups.Count > 1)
                {
                    res = res.Replace(usermatch.Groups[0].Value.ToString(), " ");
                    res = res.Trim();
                }
                if (res.Length <= 5 && res.Length<title.Length)
                {
                    int a = 0;
                    res = title;
                }

            }
            catch (System.Exception ex)
            {
                H31Debug.PrintLn(ex.Message);
                res = title;
            }
            return res;
        }

5.判斷文件名是中英文,日文等信息存儲到不一樣的表中;

        //判斷是不是中文,若是是日文等,則存儲到另一個表中
        private int ISChineseAndEnglist(string title)
        {
            try
            {
                string pattern = @"[\uac00-\ud7ff]+";//判斷韓語   
                Match usermatch = Regex.Match(title, pattern, RegexOptions.IgnoreCase);
                if (usermatch.Groups.Count >= 1 && usermatch.Groups[0].Value.Length >= 1)
                    return 0;

                pattern = @"[\u0800-\u4e00]+";//判斷日語   
                usermatch = Regex.Match(title, pattern, RegexOptions.IgnoreCase);
                if (usermatch.Groups.Count >= 1 && usermatch.Groups[0].Value.Length >= 1)
                    return 0;

                pattern = @"[\u4e00-\u9fa5]+";//判斷漢字
                usermatch = Regex.Match(title, pattern, RegexOptions.IgnoreCase);
                if (usermatch.Groups.Count >= 1 && usermatch.Groups[0].Value.Length >= 1)
                    return 1;

                //判斷英文,數字
                byte[] byte_len = System.Text.Encoding.Default.GetBytes(title);
                if (byte_len.Length == title.Length)
                    return 1;

            }
            catch (System.Exception ex)
            {
                H31Debug.PrintLn(ex.Message);
            }
            return 0;
        }

開源地址:https://github.com/h31h31/H31DHTMgr

 程序下載:H31DHT下載

下一文章準備對DHT的研究進行文章介紹.若是你們推薦度比較高,我下一步過兩天就開源C++寫的H31DHT數據抓取數據的程序,程序都是採用VS2005編寫.

 

第一次運行H31DHTMgr程序可能沒有數據,能夠先從從 http://torrage.com/sync 下載一個TXT文件回來進行處理 ;

第一次運行H31DHT數據抓取程序可能好久纔有幾要數據回來,DHT網絡好像對固定IP的比較喜歡,返回信息比較多,因此ADSL的抓取速度也不會很快.

 

因爲DHT獲取的種子內容帶AV內容的多不少,因此不提供ASP網站查詢的代碼工做,若是提供境外服務器測試,能夠提供ASP網站查詢代碼.

但願有興趣的朋友一塊兒把這個後臺管理程序修改得更加完美一些.

因爲第一次開源做品,但願你們推薦.  

相關文章
相關標籤/搜索