扒开腿挺进岳湿润的花苞视频|将军边走边挺进她H树林|挺进朋友人妻张婉莹身体|岳脱得精光让我挺进去视频|第一次挺进莹莹的身体里视频|脱岳裙子从后面挺进去视频

新疆軟件開發(fā)

本站首頁 軟件開發(fā) 成功案例 公司新聞 公司簡介 客服中心 軟件技術(shù) 網(wǎng)站建設(shè)
  您現(xiàn)在的位置: 新疆二域軟件開發(fā)公司 >> 開發(fā)語言 >> 文章正文

網(wǎng)絡(luò)編程中怎樣得知一次數(shù)據(jù)已經(jīng)收完?

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

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

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

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

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

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

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

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

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

還請各位高人多多指教!

這個(gè)代理已經(jīng)放到codeplex上,大家有興趣可以看看:http://www.codeplex.com/XProxy/

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

  • 上一篇文章:

  • 下一篇文章:

  • 相關(guān)文章:
    使用Response.Redirect時(shí)ry失效 -asp.net中
    復(fù)制SQL 數(shù)據(jù)庫時(shí)的問題
    怎樣的情況下 可以更新數(shù)據(jù)
    如何使用高效數(shù)據(jù)檢索優(yōu)化SQL Server應(yīng)用程序性能
    軟件技術(shù)
    · 開發(fā)語言
    · Java技術(shù)
    · .Net技術(shù)
    · 數(shù)據(jù)庫開發(fā)
    最新文章  
    ·搜集整理的asp.net的驗(yàn)證方
    ·各種FOR循環(huán)結(jié)構(gòu)的整理
    ·軟件項(xiàng)目開發(fā)中應(yīng)該考慮那
    ·搜集整理的javascript sel
    ·軟件開發(fā)中項(xiàng)目經(jīng)理有那些
    ·學(xué)習(xí)如何在Lambda表達(dá)式進(jìn)
    ·C++基礎(chǔ)知識(shí):結(jié)構(gòu)體數(shù)據(jù)的
    ·C#實(shí)現(xiàn)短信發(fā)送程序的例子
    ·sun最近修補(bǔ)了一部分java的
    ·rss定制的另外一種實(shí)現(xiàn)方式
    ·delphi實(shí)現(xiàn)利用arp欺騙來實(shí)
    ·基礎(chǔ)學(xué)習(xí):基于WF的流程框
    ·網(wǎng)絡(luò)編程中怎樣得知一次數(shù)
    ·如何逆序輸出單鏈表?
    ·軟件開發(fā)過程中的性能設(shè)計(jì)
    關(guān)于我們 | 軟件開發(fā) | 下載試用 | 客服中心 | 聯(lián)系我們 | 友情鏈接 | 網(wǎng)站地圖 | 新疆電子地圖 | RSS訂閱
    版權(quán)所有 © 2016 新疆二域軟件開發(fā)網(wǎng) m.jdtbank.com All Rights Reserved 新ICP備14003571號
    新疆軟件開發(fā)總機(jī):0991-4842803、4811639.
    客服QQ:596589785 ;地址:新疆烏魯木齊北京中路華聯(lián)大廈A-5C 郵編:830000
     
    文昌市| 华容县| 广东省| 天全县| 青铜峡市| 洛隆县| 泾阳县| 新巴尔虎右旗| 称多县| 隆化县| 永城市| 潮安县| 中牟县| 沁阳市| 巴中市| 曲阜市| 诸城市| 临安市| 平泉县| 陇西县| 广元市| 沐川县| 湟中县| 南昌县| 泽库县| 镇江市| 临邑县| 通河县| 远安县| 绿春县| 闸北区| 姚安县| 古田县| 宝鸡市| 宜春市| 新竹县| 屯留县| 亚东县| 兴海县| 惠州市| 高唐县|