新(xīn)疆軟件開發

本站首頁(yè) 軟件開發 成功案例 公(gōng)司新(xīn)聞 公(gōng)司簡介 客服中(zhōng)心 軟件技(jì )術 網站建設
  您現在的位置: 新(xīn)疆二域軟件開發公(gōng)司 >> 開發語言 >> 文(wén)章正文(wén)

網絡編程中(zhōng)怎樣得知一次數據已經收完?

     兩年前用(yòng).net 2.0做了一個反向代理(lǐ)服務(wù)器,在這兩年時間裏,不斷修改BUG以及優化性能(néng),使得可(kě)用(yòng)性大大提高。近來碰到一個功能(néng)需求,實在無法找出有(yǒu)效的解決辦(bàn)法,隻好上來請教各位高人。
    先說說反向代理(lǐ)的工(gōng)作(zuò)機理(lǐ)吧。
1、客戶端通過浏覽器訪問反向代理(lǐ)的時候,會發出一個HTTP請求,反向代理(lǐ)收到這個TCP連接的時候,建立一個新(xīn)的會話用(yòng)于處理(lǐ)這個請求(BeginAccept、EndAccept);
2、會話對象建立一個從客戶端接收數據的委托,開始異步讀取數據(BeginRead);
3、取得數據時,進入異步讀取的回調函數中(zhōng),開始處理(lǐ)數據(EndRead);
4、檢查反向代理(lǐ)與服務(wù)器的連接是否已建立,如果沒有(yǒu)建立,那麽需要先建立連接(ConnectServer),并建立服務(wù)器的異步讀取委托(BeginRead);
5、把數據異步寫入服務(wù)器(BeginWrite);
6、重新(xīn)建立客戶端異步讀取委托(BeginRead),回到3;
7、收到服務(wù)器返回數據時,處理(lǐ)後,異步寫入客戶端(BeginWrite);
8、重新(xīn)建立服務(wù)器異步讀取委托(BeginRead),回到7;

所有(yǒu)的數據傳輸,都使用(yòng)異步來完成,而隻需要在3和7處為(wèi)業務(wù)編寫數據處理(lǐ)代碼即可(kě)。
實際上,對于反向代理(lǐ)來說,隻需要處理(lǐ)客戶端發來的數據就可(kě)以了,需要把HTTP的HOST頭替換為(wèi)真實服務(wù)器,而對于服務(wù)器響應的數據,隻需要原樣發送給客戶端就可(kě)以了。

在步驟3中(zhōng),我們隻知道當前收到了客戶端發來的數據,而不知道這個數據是不是Http請求頭,或者是完整的Http請求頭。幸好,對于反向代理(lǐ)來說,不需要關心是否是完整的Http請求頭,隻需要檢查是否是Http請求頭,如果是,就修改Host即可(kě)。在這裏,我假設Http請求的第一個數據包肯定是獨立的數據包,不會“粘”在TCP連接中(zhōng)上一次數據的後面,這樣就可(kě)以直接使用(yòng)Http協議規定的格式來檢查這個數據包是否Http請求頭了。雖然這個假設沒有(yǒu)什麽依據,但它确實非常有(yǒu)效。

程序就這樣工(gōng)作(zuò)了兩年,沒有(yǒu)什麽問題。

但接下來,問題就出現了,有(yǒu)一個需求,要求能(néng)夠把服務(wù)器返回的頁(yè)面中(zhōng)的某個字符串替換為(wèi)指定的字符串。比如我用(yòng)反向代理(lǐ)指向博客園,我就需要把博客園頁(yè)面中(zhōng)所有(yǒu)使用(yòng)了絕對路徑的連接修改為(wèi)指向反向代理(lǐ)服務(wù)器的連接。這就要求在步驟7這裏處理(lǐ)數據,把數據轉為(wèi)字符串,然後替換鏈接,然後才發往客戶端。

但步驟7每次收到的數據隻是一個片段,而不是整個頁(yè)面的HTML。即使我們再次假設Http響應的第一個數據包是獨立的數據包,也隻能(néng)識别哪些是響應頭,哪些是數據體(tǐ)而已。也想過每一段數據轉為(wèi)這一段的字符串進行處理(lǐ),但是,如果剛好某個字符被網絡層拆分(fēn)到兩個TCP數據包裏怎麽辦(bàn)?還有(yǒu),想博客園這樣使用(yòng)了gzip的,如果不接受完整個頁(yè)面的數據,是無法解壓的;就算這兩種情況都不存在,而網絡層剛好在超鏈接的地方拆分(fēn)數據包怎麽辦(bàn)?

因此,最保守的做法就是拿(ná)到整個頁(yè)面數據再開始處理(lǐ)。也想過Http響應頭那裏有(yǒu)個Content-Length指明内容長(cháng)度的,但實際中(zhōng),很(hěn)多(duō)響應根本就不到這個段。

我查看過HttpListener類和HttpListenerRequest類,嘗試從中(zhōng)發現它是如何接受完一次請求(響應)的,可(kě)惜這兩個類調用(yòng)了大量NativeAPI,就無法得知了。

還有(yǒu)浏覽器,它又(yòu)是如何得知某次響應是否已經完成的呢(ne)?

還請各位高人多(duō)多(duō)指教!

這個代理(lǐ)已經放到codeplex上,大家有(yǒu)興趣可(kě)以看看:http://www.codeplex.com/XProxy/

作(zuò)者:新(xīn)生命 | 文(wén)章來源:cnblogs | 更新(xīn)時間:2008-3-10 17:27:31

  • 上一篇文(wén)章:

  • 下一篇文(wén)章:

  • 相關文(wén)章:
    使用(yòng)Response.Redirect時ry失效 -asp.net中(zhōng)
    複制SQL 數據庫時的問題
    怎樣的情況下 可(kě)以更新(xīn)數據
    如何使用(yòng)高效數據檢索優化SQL Server應用(yòng)程序性能(néng)
    軟件技(jì )術
    · 開發語言
    · Java技(jì )術
    · .Net技(jì )術
    · 數據庫開發
    最新(xīn)文(wén)章  
    ·搜集整理(lǐ)的asp.net的驗證方
    ·各種FOR循環結構的整理(lǐ)
    ·軟件項目開發中(zhōng)應該考慮那
    ·搜集整理(lǐ)的javascript sel
    ·軟件開發中(zhōng)項目經理(lǐ)有(yǒu)那些
    ·學(xué)習如何在Lambda表達式進
    ·C++基礎知識:結構體(tǐ)數據的
    ·C#實現短信發送程序的例子
    ·sun最近修補了一部分(fēn)java的
    ·rss定制的另外一種實現方式
    ·delphi實現利用(yòng)arp欺騙來實
    ·基礎學(xué)習:基于WF的流程框
    ·網絡編程中(zhōng)怎樣得知一次數
    ·如何逆序輸出單鏈表?
    ·軟件開發過程中(zhōng)的性能(néng)設計
    關于我們 | 軟件開發 | 下載試用(yòng) | 客服中(zhōng)心 | 聯系我們 | 友情鏈接 | 網站地圖 | 新(xīn)疆電(diàn)子地圖 |
    版權所有(yǒu) © 2016 新(xīn)疆二域軟件開發網 www.k8w.net All Rights Reserved 新(xīn)ICP備14003571号
    新(xīn)疆軟件開發總機:0991-4842803、4811639.
    客服QQ:596589785 ;地址:新(xīn)疆烏魯木(mù)齊北京中(zhōng)路華聯大廈A-5C 郵編:830000