<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # ASP.NET - 將 ASP.NET 用作高性能文件下載器 作者?[Doug Duerner](https://msdn.microsoft.com/zh-cn/magazine/mt149362?author=Doug+Duerner)、[Yeon-Chang Wang](https://msdn.microsoft.com/zh-cn/magazine/mt149362?author=Yeon-Chang+Wang)?| 2015 年 11 月 | 獲取代碼:?[C#](http://download.microsoft.com/download/B/A/E/BAEA7711-903C-4536-92FF-CAC9955EB848/Code_DuernerWangFileDownloader1115.zip)[VB](http://download.microsoft.com/download/B/A/E/BAEA7711-903C-4536-92FF-CAC9955EB848/VBCode_DuernerWangFileDownloader1115.zip) 緩慢故障連接一直都是大型文件下載問題的癥結所在。您可能會在機場大廳用不完善的 WiFi 連接收集媒體,以便在長途飛行中制作演示文稿;也可能會在非洲大草原上嘗試通過太陽能水泵的衛星鏈接下載大型安裝文件。無論是哪種情況,大型文件下載故障的代價都是相同的:既浪費了時間、使人心力交瘁,還存在無法完成任務的危險。 但并不一定會到如此地步。在本文中,我們將展示如何創建實用工具來解決恢復和繼續失敗下載的問題,此問題是由于大型文件傳輸過程中易于脫機的狀況不佳連接所致。 ## 背景 我們希望能創建簡單的文件下載器實用工具,并用極其簡單且易于使用的客戶端程序(或僅使用 Web 瀏覽器作為客戶端)將此實用工具輕松地添加到您現有的 IIS Web 服務器中。 事實證明,IIS Web 服務器是高度可擴展的企業級 Web 服務器,可在多年內向瀏覽器提供文件。我們基本上是想利用 IIS Web 服務器同時并行處理多個 HTTP Web 請求的能力,并將其應用于文件下載(復制)。 從根本上講,我們需要的是能夠為世界各地的用戶下載大型文件的文件下載器實用工具,這些用戶有時會位于偏遠地區,只能使用經常發生故障的緩慢網絡鏈接。由于某些處于世界偏遠地區的用戶仍可能在使用可能會隨機脫機或周期性地切換聯機和脫機狀態的調制解調器鏈接或故障的衛星鏈接,因此實用工具必須極具復原性,能夠僅重新下載無法下載的文件部分。我們不希望用戶將整個晚上的時間都浪費在用緩慢鏈接下載大型文件上。如果網絡鏈接出現一個小問題,就需要重新開始整個下載流程。我們還需要確保這些下載的大型文件不會在服務器內存中緩沖,且服務器內存使用量最低。這樣一來,當多位用戶同時下載文件時,內存使用量就不會持續增加,也就不會導致服務器故障。 反之,如果用戶足夠幸運,擁有可靠的高速網絡鏈接(其客戶端和服務器計算器均為配備了多個 CPU 和網卡的高端計算機),我們希望用戶能夠使用多線程和多連接來下載文件,這樣文件的多個區塊就能夠使用所有硬件資源同時并行下載,同時確保服務器內存使用量最低。 簡而言之,我們創建的是簡單的文件下載實用工具,不僅能多線程并行下載,還能確保較低的內存使用率。它可以將文件分成幾個區塊、在單獨的線程上下載各個區塊,并允許用戶僅重新下載無法下載的區塊。 本文中隨附的示例項目包括文件下載實用工具的代碼,并提供了將來可擴展的最基本基礎結構,使您能夠根據需要設計更復雜的結構。 ## 示例項目概述 從本質上講,DownloadHandler.dll 將現有的 IIS Web 服務器轉換成多線程文件下載器,讓您能夠使用獨立可執行客戶端 (FileDownloader.exe) 中的簡單 URL 將文件分成幾個區塊并行下載,如圖 1?所示。請注意,參數 (chunksize=5242880) 是可選的。如果未包括在內,則默認為通過一個區塊下載整個文件。圖 2?和圖 3?展示了您如何能夠反復地重新下載無法下載的文件部分,直到成功下載為止,而不用像其他大多數文件下載軟件那樣從頭開始完全重新下載整個文件。 ![](https://box.kancloud.cn/2016-01-08_568f30b58f5ec.png)? 圖 1:DownloadHandler.dll 處理流的簡略設計概覽(將 FileDownloader.exe 用作客戶端) ![](https://box.kancloud.cn/2016-01-08_568f30b5ae17d.png)? 圖 2:獨立可執行的下載客戶端(含無法下載的區塊) ![](https://box.kancloud.cn/2016-01-08_568f30b5d4566.png)? 圖 3:獨立可執行的下載客戶端(重試后) 圖 1?是 DownloadHandler.dll 和 FileDownloader.exe 的簡略設計概覽,將處理流展示為,服務器計算機的硬盤驅動器上的文件區塊通過 DownloadHandler.dll 和 FileDownloader.exe 進入客戶端計算機的硬盤驅動器上的文件,同時展示了這一流程中包含的 HTTP 協議標頭。 在圖 1?中,FileDownloader.exe 通過使用簡單的 URL 調用服務器來啟動文件下載,URL 包含要下載的文件名稱,作為 URL 查詢字符串參數 (file=file.txt),并在內部使用 HTTP 方法 (HEAD)。所以,服務器最初只會發送回其響應頭,其中一個包含總文件大小。然后,客戶端會使用 Parallel.ForEach 構造進行循環訪問,根據參數中的區塊大小 (chunksize=5242880) 將總文件大小拆分成各個區塊大小(字節范圍)。對于各個循環訪問,Parallel.ForEach 構造會在單獨的線程上執行處理方法,傳遞關聯的字節范圍。在處理方法中,客戶端會使用相同的 URL 向服務器發出 HttpWebRequest 調用,并在內部附加 HTTP 請求頭,其中包含提供給處理方法的字節范圍(即 Range: bytes=0-5242880、Range: bytes=5242880-10485760 等)。 在服務器計算機上,我們的 IHttpAsync-Handler 接口 (System.Web.IHttpAsyncHandler) 實現可在單獨線程上處理各個請求,同時執行 HttpResponse.Transmit-File 方法,以便將服務器計算機中的文件請求獲取的字節范圍直接寫入網絡流(無顯式緩沖),所以對服務器的內存影響幾乎不存在。服務器會發送回具有 HTTP 狀態代碼 206 (PartialContent) 的響應,并在內部附加可標識返回的字節范圍的 HTTP 響應頭(即 Content-Range: bytes 0-5242880/26214400、Content-Range: bytes 5242880-10485760/26214400 等)。由于每個線程都會在客戶端計算機上收到 HTTP 響應,因此,它會將響應中返回的字節寫入客戶端計算機硬盤驅動器上的文件的相應部分,這會在 HTTP 響應頭 (Content-Range) 中進行標識。它使用異步重疊文件 I/O(以確保 Windows I/O 管理器不會在將 I/O 請求數據包分派給內核模式驅動程序以便完成文件寫入操作之前,將 I/O 請求串行化)。如果多個用戶模式線程全都在執行文件寫入,但您沒有為異步重疊 I/O 打開文件,則請求會進行串行化,且內核模式驅動程序一次只會收到一個請求。有關異步重疊 I/O 的更多信息,請參閱硬件開發者中心網站上的“讓驅動程序一次處理多個 I/O 請求”([bit.ly/1NIaqxP](http://bit.ly/1NIaqxP)) 和“支持異步 I/O”([bit.ly/1NIaKMW](http://bit.ly/1NIaKMW))。 為了在我們的 IHttpAsyncHandler 上實現異步性,我們會將重疊的 I/O 結構手動發布到 I/O 完成端口,且 CLR ThreadPool 會在完成端口線程上運行重疊結構中提供的完成委托。這些與大多數內置異步方法所用的完成端口線程相同。一般來說,最好對大部分 I/O 工作使用全新的內置異步方法,但在此示例中,我們希望使用 HttpResponse.TransmitFile 函數,因為它具備出色的大型文件傳輸能力,而不會在服務器內存中進行顯式緩沖。太不可思議了! Parallel.ForEach 主要用于 CPU 工作,由于它具有屏蔽特質,因此絕不應將其真正用于服務器實現。我們將這項工作分流至 CLR ThreadPool 中的完成端口線程(而非 CLR ThreadPool 中的常規工作線程),以避免消耗 IIS 使用的相同線程來服務于傳入請求。此外,完成端口更有效地處理工作多少會限制服務器上的線程消耗。在同一示例項目代碼中,IOThread 類頂部的注釋部分中列出了圖解和更詳細的說明,其中突出顯示了 CLR ThreadPool 中的完成端口線程和工作線程的區別。由于擴展到數百萬用戶并非此實用工具的主要目標,因此,我們能夠承受消耗所需的其他服務器線程來運行 HttpResponse.TransmitFile 函數,以便在傳輸大型文件時節省相關服務器內存。從根本上講,我們是在以損失可伸縮性為代價,導致這種損失的原因是在服務器上使用其他線程(而不是無線程的內置異步方法),以便使用 HttpResponse.TransmitFile 函數,這樣消耗的服務器內存極低。雖然這已經超出了本文的范圍,但您可以視需要選擇將內置異步方法與無緩沖的文件 I/O 結合使用,以實現相似的內存節省效果,而無其他任何線程。不過,據我們了解,一切都必須按扇區對齊,正確實現起來稍微有些困難。除此之外,Microsoft 似乎是特意從 FileOptions 枚舉中刪除了 NoBuffering 項,以便真正避免無緩沖的文件 I/O(需要手動獲取才能如愿以償)。我們對與未正確實現相關的風險持相當緊張的態度,并決定了采用風險較低的 HttpResponse.TransmitFile 選項(已經過全面測試)。 FileDownloader.exe 能夠啟動多個線程,每個線程都會根據總文件大小如何劃分成指定的“區塊字節”,發出與所下載文件的各個區塊(字節范圍)相對應的單獨 HttpWebRequest 調用,如圖 2?所示。 只需重復執行相同的 HttpWebRequest 調用(僅針對失敗的字節范圍),即可重試任何無法下載 HttpWebRequest 調用中指定的文件部分(字節范圍)的線程,直至最終成功下載為止,如圖 3?所示。您不會丟失已下載的文件部分,如果連接速度緩慢,則可能意味著節省數小時的下載時間。您幾乎可以消除不斷脫機的故障連接造成的不利影響。利用以多線程同時并行下載文件的不同部分的設計(無顯式緩沖,直接寫入網絡流),以及下載到帶有異步重疊文件 I/O 的硬盤驅動器上的設計,如果實際聯機的是不可靠的連接,則您可以在一段時間內最大限度地增加完成的下載數量。此工具會在網絡鏈接每次恢復聯機時繼續完成剩余的部分,而不會丟失任何作業。我們更愿意將它看作是“可重試的”文件下載器,而不是“可恢復的”文件下載器。 可以通過假設的示例來闡述這兩者之間的區別。您將要下載一個大型文件,需要整晚上的時間。您在下班時啟動可恢復的文件下載器,并讓其一直運行。當您第二天早上來上班時,您發現文件下載在 10% 處就失敗了,并已準備好恢復下載。但在恢復時,它仍需要重新運行整個晚上才能完成剩余的 90%。 相比之下,您在下班時啟動可重試的文件下載器,并讓其整晚運行。當您第二天早上來上班時,您發現文件下載在 10% 處有一個區塊失敗了,但仍繼續下載了文件的剩余區塊。現在,您只需重新下載無法下載的那個區塊,就大功告成了。在遇到因短暫的網絡鏈接問題而無法下載的那個區塊后,它會在網絡鏈接恢復聯機后用這一晚的剩余時間繼續并完成剩余的 90%。 使用 URL(如 https://localhost/DownloadPortal/Download?file=test.txt&chunksize=5242880),也可以將 Web 瀏覽器內置的默認下載客戶端用作下載客戶端。 請注意,在將 Web 瀏覽器用作下載客戶端時,參數 (chunksize=5242880) 也是可選的。如果未包括在內,則服務器會使用相同的 HttpResponse.TransmitFile 通過一個區塊下載整個文件。如果包括在內,則會為每個區塊單獨執行 HttpResponse.TransmitFile 調用。 圖 4?展示了在將不支持部分內容的 Web 瀏覽器用作下載客戶端時,DownloadHandler.dll 的簡略設計概覽。圖中將處理流展示為,服務器計算機的硬盤驅動器上的文件區塊通過 DownloadHandler.dll 和 Web 瀏覽器進入 Web 瀏覽器計算機的硬盤驅動器上的文件。 ![](https://box.kancloud.cn/2016-01-08_568f30b5f36a0.png)? 圖 4:DownloadHandler.dll 處理流的簡略設計概覽(將不支持部分內容的 Web 瀏覽器用作客戶端) 在 IIS Web 服務器上實現 IHttpAsyncHandler 接口提供了一項精彩功能,即通過在 HTTP 響應中發送 Accept-Ranges HTTP 標頭 (Accept-Ranges: bytes) 來支持“字節提供”,這會告知客戶端它將提供文件的各個部分(部分內容范圍)。如果 Web 瀏覽器內的默認下載客戶端支持部分內容,則它能夠在 HTTP 請求中向服務器發送 Range HTTP 標頭 (Range: bytes=5242880-10485760);當服務器將部分內容發送回客戶端時,它會在 HTTP 響應中發送回 Content-Range HTTP 標頭 (Content-Range: bytes 5242880-10485760/26214400)。因此,您可以獲得部分與我們的獨立可執行客戶端相同的優勢,具體視您所使用的 Web 瀏覽器和瀏覽器中內置的默認下載客戶端而定。無論如何,大部分 Web 瀏覽器都會允許您構建您自己的自定義下載客戶端,并將其插入瀏覽器中,替換內置的默認客戶端。 ## 示例項目配置 對于示例項目,只需將 DownloadHandler.dll 和 IOThreads.dll 復制到虛擬目錄下的 \bin 目錄中,并將條目放入 web.config 中的處理程序部分和模塊部分即可,如下所示: ~~~ <handlers> ? <add name="Download" verb="*" path="Download" ??? type="DownloaderHandlers.DownloadHandler" /> </handlers> <modules> ? <add name="CustomBasicAuthenticationModule" preCondition="managedHandler" ??? type="DownloaderHandlers.CustomBasicAuthenticationModule" /> </modules> ~~~ 如果 IIS 服務器上沒有任何虛擬目錄,請創建一個包含 \bin 目錄的虛擬目錄,使其投入使用,并確保它使用的是 Microsoft.NET Framework 4 應用程序池。 自定義的基本身份驗證模塊使用易用的 AspNetSqlMembershipProvider,與當前許多 ASP.NET 網站使用的一樣,同時在 SQL 服務器上的 aspnetdb 數據庫中存儲下載文件所需的用戶名和密碼。使用 AspNetSqlMembershipProvider 即可獲得的優勢之一是,用戶無需在 Windows 域上擁有帳戶。有關如何安裝 AspNetSqlMembershipProvider 以及配置用戶帳戶和 SSL 證書所需的 IIS 服務器設置的詳細說明,請轉到示例項目代碼,參閱 CustomBasicAuthentication-Module 類頂部的注釋部分中列出的說明。用于優化 IIS 服務器的其他高級配置選項通常已由管理服務器的 IT 部門進行了設置,并且此內容不在本文的范圍內。不過,如果還未配置,您可訪問?[bit.ly/1JRJjNS](http://bit.ly/1JRJjNS)?上的 TechNet 庫,了解相關信息。 至此大功告成。就是這么簡單。 ## 備受矚目的因素 本設計最備受矚目的因素不僅包括它能提高速度,還包括它對因不可靠、不穩定的網絡鏈接不斷切換聯機和脫機狀態而引起的網絡中斷更具復原性和容錯性。通常情況下,借助一個連接并通過一個區塊來下載一個文件的吞吐量最高。 此規則也有一些獨特的例外,如鏡像服務器環境。在這一環境中,文件是通過單獨的區塊下載,文件的每一區塊都是從不同的鏡像服務器中獲得,如圖 5?所示。然而,一般來說,通過多線程下載文件實際上要比通過單線程下載文件慢,因為網絡通常是瓶頸。不過,能夠僅反復地重新下載無法下載的文件部分,直至成功下載為止,而無需重啟整個下載流程,我們認為這在某種程度上就類似于容錯。 ![](https://box.kancloud.cn/2016-01-08_568f30b614626.png) 圖 5:假設的未來增強功能以便模擬最基本的鏡像基礎結構 此外,如果有人要將這一設計修改為未來增強功能以便模擬最基本的鏡像服務器基礎結構(如圖 5?所示),則可以認為是類似于容錯。 從根本上講,通過這一設計,您可以通過不可靠的網絡可靠地下載文件。網絡鏈接上短暫出現的問題并不表示您必須從頭開始下載;相反,您可以只重新下載無法下載的文件區塊。此設計的附加優勢(可提高復原性)在于,您可在下載的同時,將文件下載的當前進度狀態存儲至硬盤驅動器上的文件中,這樣您就可以基本上跨客戶端應用程序和客戶端計算機重啟重新下載無法下載的部分了。不過,這是留給讀者的練習。 另一個備受矚目的因素(在突出程度上與之前提到的因素相媲美)在于,使用服務器上的 HttpResponse.TransmitFile 直接將文件字節寫入網絡流(無顯式緩沖),從而最大限度地將對服務器內存的影響降至最低。令人驚訝的是,這對服務器內存的影響微乎其微,甚至是在下載極大的文件時。 還有其他三個并不那么重要的因素,但它們依然備受矚目。 首先,由于設計包括前端客戶端和后端服務器,因此您可以完全控制服務器端配置。這樣一來,您便可以自由地調整配置設置,這些設置經常會極大地妨礙服務器上的文件下載流程。這些服務器屬于其他人,不受您的控制。例如,您可以將每個客戶端 IP 地址限定的連接限制調整為一個大于常規限制(兩個連接)的值。您也可以將每個客戶端連接的限制調整為更大的值。 其次,我們的前端客戶端 (FileDownloader.exe) 和后端服務器 (DownloadHandler.dll) 中的示例項目代碼能夠用作簡單明確的示例代碼塊,用于展示 如何使用在 HTTP 協議中支持部分內容字節范圍所需的 HTTP 請求頭和響應頭。客戶端為了請求獲得字節范圍而必須發送的 HTTP 請求頭,以及服務器為了將字節范圍作為部分內容返回而必須發送的 HTTP 響應頭,都很容易就能看出來。將代碼修改為實現更高級別的功能(在這一簡單的基本功能之上),或者實現更復雜的軟件包中可用的部分更高級功能,應該相對簡單。此外,您還可以將它用作簡單的起始模板,以便您可以相對輕松地添加對其他一些更高級的 HTTP 標頭(例如,Content-Type: multipart/byteranges、Content-MD5: md5-digest、If-Match: entity-tag 等)的支持。 第三,由于設計使用的是 IIS Web 服務器,因此您可以自動受益于服務器提供的一些內置功能。例如,通信可以自動加密(使用帶 SSL 證書的 HTTPS)和壓縮(使用 gzip 壓縮)。不過,如果對極大的文件運行 gzip 壓縮會對您的服務器 CPU 造成太大的壓力,那么我們不建議您這樣做。然而,如果您的服務器 CPU 能夠承受額外的負擔,則傳輸小得多的壓縮數據的效率有時會對整個系統的總吞吐量造成巨大影響。 ## 未來改進 示例項目代碼只提供了讓文件下載器運行至少所需的核心功能。我們的目標是讓設計簡單易懂,以便用戶能夠相對輕松地將其用作基本設計,并以此為基礎添加增強功能和額外功能。這只是作為起始的基本模板。在開始用于生產環境之前,絕對有必要添加其他許多增強功能。添加能夠額外提供這種更高級的功能的更高級別抽象層是留給讀者的練習。不過,我們將會闡述幾項更至關重要的增強功能。 示例項目代碼暫未在文件中添加 MD5 哈希校驗和。事實上,有必要采用某種文件校驗和策略,以確保下載到客戶端的文件與服務器上的文件是一致的,且文件未受到任何形式的篡改或更改。HTTP 標頭 (Content-MD5: md5-digest) 讓這變得簡單。實際上,其中就包含我們首批原型中的一個,它在每次有文件請求時,就對文件執行 MD5 哈希校驗和,并在文件離開服務器之前,將摘要插入標頭 (Content-MD5: md5-digest) 中。然后,客戶端會對收到的文件執行相同的 MD5 哈希校驗和,并驗證生成的摘要是否與服務器返回的標頭 (Content-MD5: md5-digest) 中的摘要一致。如果不一致,則說明文件受到了篡改或損壞。雖然這完成了確保文件未被更改的目標,但大型文件會對服務器 CPU 造成巨大壓力,而且執行時間也會過長。 實際上,可能需要某種高速緩存層對文件執行 MD5 哈希校驗和處理(在后臺,一次即可覆蓋整個文件生命周期),并將生成的摘要存儲在字典中(將文件名用作密鑰)。這樣一來,在服務器上獲取文件的摘要只需執行簡單的字典查找即可,在文件離開服務器時可以將摘要添加到標頭中(瞬間完成),對服務器 CPU 造成的影響也最小。 示例項目代碼也暫未限制客戶端使用數量龐大的線程并將文件拆分成大量的區塊。它基本上允許客戶端執行“需要的操作”來確保其能夠下載文件。實際上,可能需要某種能夠對客戶端施加限制的基礎結構,這樣一個客戶端就無法盜用服務器,也無法使其他任何客戶端停止了。 圖 5?展示了假設的未來增強功能以便模擬最基本的鏡像基礎結構,主要是通過將設計修改為提供“節點名稱/字節范圍”對列表作為 URL 查詢字符串參數,而不是使用當前設計的“chunksize”參數。您可以相對輕松地將當前設計修改為,僅通過循環訪問“節點名稱/字節范圍”對,為每個對啟動 HttpWebRequest,從而從不同的服務器中獲取文件的每個區塊,而不用通過內部循環訪問來根據“chunksize”參數將總文件大小拆分成各個區塊大小,并為每個區塊啟動 HttpWebRequest。 您可以僅用“節點名稱/字節范圍”對列表中的相關節點名稱替換服務器名稱,將相關字節范圍添加到 Range HTTP 標頭(即,Range: bytes=0-5242880),然后將“節點名稱/字節范圍”列表從 URL 中完全刪除,以此來為 HttpWebRequest 構造 URL。某種元數據文件可以確定文件區塊所在的服務器,然后請求計算機能夠從分布在不同服務器上的文件區塊中組合出一個文件。 如果某文件有 10 個鏡像服務器,則您可以將設計修改為從服務器 1 鏡像副本上獲取文件區塊 1,從服務器 2 鏡像副本上獲取文件區塊 2,從服務器 3 鏡像副本上獲取文件區塊 3,依此類推。同樣,在您檢索了文件的所有區塊,并在客戶端上組合出了完整的文件后,有必要對文件執行 MD5 哈希校驗和,以確保所有鏡像服務器上的文件區塊均未損壞,且您確實收到了整個文件。您甚至可以讓設計變得花哨一點,并上升到新的高度,即跨整個國家/地區分布服務器,讓代碼智能起來,使其能夠確定哪些服務器的處理負載最小,然后使用這些服務器服務于返回文件區塊的請求。 ## 總結 我們的設計并不以創建更快速、更可縮放的文件下載器為目標,而是以創建一個對瞬時網絡中斷具有極強復原性的文件下載器為目標。 我們不遺余力地確保設計極為簡單,并能明確地展示如何對“字節提供”字節范圍和部分內容使用 HTTP 協議標頭。 在研究中,我們發現,要找到一個明確的實用示例來展示如何執行簡單的 HTTP 字節提供,以及如何在 HTTP 協議中正確使用字節范圍標頭確實相當困難。大多數示例要么過于復雜,要么使用了其他許多標頭在 HTTP 協議中實現更多高級功能,使其難以理解,更不用說今后進行增強或擴展了。 我們想為您提供簡單堅實的基礎設計,其中只包括最低限度的必要功能,以便您可以相對容易地進行實驗,并隨著時間的推移逐步添加更多高級功能,或者甚至實現整個更高級別的抽象層來添加 HTTP 協議的一些更高級功能。 我們只想為您提供直觀的示例,以供您學習并以此為基礎進行構建。請盡情體驗吧! * * * Doug Duerner?*是一名高級軟件工程師,在使用 Microsoft 技術設計和實現大型系統方面擁有超過 15 年的經驗。他曾就職于多家財富 500 強銀行機構和一家商業軟件公司,這家公司設計并構建大型分布式網絡管理系統,以供美國國防部國防信息系統局 (DISA)(用于其“全球信息網絡”)和美國國務院使用。他有一顆極客的心,專注于各個方面,對最復雜且具有挑戰性的技術難題情有獨鐘,尤其是那些大家都說“無法完成”的事情。 您可以通過?[coding.innovation@gmail.com](mailto:coding.innovation@gmail.com)?與 Duerner 取得聯系。* Yeon Chang Wang?*是一名高級軟件工程師,在使用 Microsoft 技術設計和實現大型系統方面擁有超過 15 年的經驗。他也曾就職于一家財富 500 強銀行機構和一家商業軟件公司,這家公司設計并構建大型分布式網絡管理系統,以供美國國防部國防信息系統局 (DISA)(用于其“全球信息網絡”)和美國國務院使用。他還為全球最大的芯片制造商之一設計并實現了大型驅動程序認證系統。Wang 獲有計算機科學專業的碩士學位。他非常喜歡解決復雜問題,您可以通過?[yeon_wang@yahoo.com](mailto:yeon_wang@yahoo.com)?與他取得聯系。*
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看