與Socket的“再次見面”

來源:互聯網
上載者:User

.NET 4.0網路開發入門之旅——

與Socket的“再次見面”

 

註:

   
這是一個針對
網路開發領域初學者
的系列文章,可作為《.NET 4.0 物件導向編程漫談



》一書的擴充閱讀,寫作過程中我假設讀者可以對照閱讀此書的相關章節,不再浪費筆墨重複介紹相關的內容。

   
對於其他類型的讀者,除非您已經有相應的.NET 技術背景與一定的開發經驗,否則,閱讀中可能會遇到困難。

   
我希望這系列文章能讓讀者領略到網路開發的魅力!

   
另外,這些文章均為本人原創,請讀者尊重作者的勞動,我允許大家出於知識共用的目的自由轉載這些文章及相關樣本,但未經本人許可,請不要用於商業盈利目的。

      本文如有錯誤,敬請回貼指正。

   
謝謝大家!

 

                                                         
金旭亮

=================================================

點擊以下連結閱讀本系列前面的文章:

 



開篇語——
無網不勝》


IP知多少》

《我在“網” 中央

《與Socket的第一次“約會”

=================================================

 

    前一篇文章介紹了與Socket的第一次“約會”經曆,看來雙方的第一印象不錯,不然讀者也不會做出一個“繼續交往”的決定,並繼續閱讀本篇文章了。 :)
    在這篇文章中,計劃介紹兩方面的內容:
    Socket的串連請求隊列和如何開發“一問一答”的網路應用程式。


    1 Socket的“串連請求隊列”


 

    在現實生活中,一名品貌俱佳的女孩總是不乏追求者,人們會打趣地說“她的追求者有一個班”,這樣的一個女孩,在同一時間段內收到多個約會請求實在是太常見的事,當然,到底接受誰的約會邀請,就要看她中意誰了。
    類似地,當一個綁定到特定終結點的Socket對象開始“監聽(Listen)”時,完全有可能有多個用戶端向此Socket同時發出多個串連請求,Socket對象必須決定如何處理這些串連請求。
    為了方便處理,作業系統也會給每個正在監聽的Socket分配一個“串連請求隊列”,將收到的用戶端串連請求追加到此隊列中:



圖 1

    由於網路伺服器上可能同時會有多個Socket同時監聽,我們應該給每個Socket對象分配一個 “適當容量”的隊列,以避免過多地佔用系統資源,讓網路伺服器能服務更多的線上使用者。


    請求隊列的容量由Socket.Listen方法的參數backlog確定:

    public void Listen(int backlog

);

    例如,以下代碼指定newSocket對象最多隻能接收10個串連請求:

    newsock.Listen(10

);

    更詳細地說,如果newSocket對象正在忙於處理某個串連請求時,作業系統又接收到了多個嘗試串連此newSocket對象的請求,作業系統會把這些請求追加到newSocket對象所關聯的請求隊列中。
    newSocket對象處理完當前串連之後,它再從關聯的請求隊列中取出一個處理。


    一個有趣的問題是:如果某一時間段內串連請求很多,請求隊列“放不下”怎麼辦?


    請看樣本解決方案ConnectionQueueDemo。這個解決方案中的MyServerApp項目與前一講
中的完全一樣,也是接收並顯示用戶端發來的一句“問好”訊息之後就斷開與此用戶端的串連。
    為了直觀地體現串連請求隊列的特性,MyServerApp項目有意識地指定一個容量為“1”的請求隊列:

    newsock.Listen(1);

    在用戶端項目MyClientApp2中,建立10個線程,每個線程都建立一個Socket對象並嘗試著串連MyServerApp程式(圖 2)。

 

   
 
圖 2

 

    我們看到了非常著名的“目標電腦積極拒絕……”的資訊,它是由以下這句英文直譯過來的:

 …… the target machine actively refused it ……

    就漢語來說,這明顯是一個病句,什麼叫“積極拒絕”?難道還有“消極拒絕”?
    由此可見負責漢化Windows的程式員要不是“語文”學得不太好,要不就是“過於死板”了,個人覺得,此處意譯為以下這句更好:
    嘗試串連的電腦拒絕了串連請求。


    從樣本中我們可以得到結論:
    當嘗試串連的用戶端發來的串連請求數目過大,超過了服務端Socket的串連請求隊列容量時,未能進入隊列的請求將會被丟棄,而用戶端將會得到一個代碼為10061的SocketException。    用戶端可以捕獲此異常,等待一定的時間再嘗試串連。




    2 開發“一問一答”的網路應用程式


    在各種網路應用程式中,“一問一答”可以說是最常見的一種類型。基於Socket實現這種類型的網路應用程式是非常簡單的:
    在服務端與用戶端配套使用Send和Receive方法,只要傳送的資料不超過緩衝區的大小限制,就可以實現“一問一答”的標準C/S架構程式。
    請看樣本解決方案EchoServiceDemo(圖 3):

 

 
圖 3

    EchoServiceDemo樣本沒什麼複雜的,大家看看樣本源碼就清楚了。


    看懂源碼後,請讀者做做以下實驗:


    (1)先運行服務端程式EchoServiceApp,然後,運行用戶端程式EchoServiceClientApp串連上服務端,與EchoServiceApp進行交談,注意不要輸入“exit”命令退出。
    (2)再運行EchoServiceClientApp的另一個執行個體,嘗試串連EchoServiceApp,發生了什嗎?
    (3)運行EchoServiceClientApp的第3個執行個體,嘗試串連EchoServiceApp,又發生了什嗎?


    你能利用已經掌握的知識解釋發生這些現象的原因嗎?從這個實驗中,您體會到了什嗎?總結出來了哪些經驗?


    進一步地,讀者現在能解決以下這個問題嗎?


    你能想辦法修改EchoServiceApp源碼,讓它同時可以服務多個用戶端應用程式嗎?

  
  提示:

    (1)在EchoServiceApp程式中為每個用戶端串連建立一個獨立的線程,在此線程中完成“一問一答”的工作。
    (2)感到困難的讀者請參看《.NET 4.0物件導向編程漫談》,系統地學習第16章《多線程開發技術基礎》。

    此處只是介紹了開發“一問一答”的網路應用程式的最基礎開發技巧,其實,這其中還有許多需要注意的“陷阱”,下一講將介紹Socket編程中最大的“陷阱”--緩衝區問題,並開發第一個真正有點實用價值的網路應用程式--網路四則運算計算機。

========================================

 


點擊下載樣本源碼


(部落格園的下載連結:http://files.cnblogs.com/bitfan/AskAndAnswerSourceCode.rar
)



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.