新疆軟件開發

本站首頁 軟件開發 成功案例 公司新聞 公司簡介 客服中心 軟件技術 網站建設
  您現在的位置: 新疆二域軟件開發公司 >> 開發語言 >> 文章正文

網絡編程中怎樣得知一次數據已經收完?

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

所有的數據傳輸,都使用異步來完成,而只需要在3和7處為業務編寫數據處理代碼即可。
實際上,對于反向代理來說,只需要處理客戶端發來的數據就可以了,需要把HTTP的HOST頭替換為真實服務器,而對于服務器響應的數據,只需要原樣發送給客戶端就可以了。

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

程序就這樣工作了兩年,沒有什么問題。

但接下來,問題就出現了,有一個需求,要求能夠把服務器返回的頁面中的某個字符串替換為指定的字符串。比如我用反向代理指向博客園,我就需要把博客園頁面中所有使用了絕對路徑的連接修改為指向反向代理服務器的連接。這就要求在步驟7這里處理數據,把數據轉為字符串,然后替換鏈接,然后才發往客戶端。

但步驟7每次收到的數據只是一個片段,而不是整個頁面的HTML。即使我們再次假設Http響應的第一個數據包是獨立的數據包,也只能識別哪些是響應頭,哪些是數據體而已。也想過每一段數據轉為這一段的字符串進行處理,但是,如果剛好某個字符被網絡層拆分到兩個TCP數據包里怎么辦?還有,想博客園這樣使用了gzip的,如果不接受完整個頁面的數據,是無法解壓的;就算這兩種情況都不存在,而網絡層剛好在超鏈接的地方拆分數據包怎么辦?

因此,最保守的做法就是拿到整個頁面數據再開始處理。也想過Http響應頭那里有個Content-Length指明內容長度的,但實際中,很多響應根本就不到這個段。

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

還有瀏覽器,它又是如何得知某次響應是否已經完成的呢?

還請各位高人多多指教!

這個代理已經放到codeplex上,大家有興趣可以看看:http://www.codeplex.com/XProxy/

作者:新生命 | 文章來源:cnblogs | 更新時間:2008-3-10 17:27:31

  • 上一篇文章:

  • 下一篇文章:

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