TCP同步與異步及阻塞模式,多線程+阻塞模式,非阻塞模式簡單介紹

首先我簡單介紹一下同步TCP編程 與異步TCP編程。

在服務端我們通常用一個TcpListener來監聽一個IP和端口。客戶端來一個請求的連接,在服務端可以用同步的方式來接收,也可以用異步的方式去接收。比如:

TcpListene server = new TcpListener(IPAddress.Parse("127.0.0.1"), port);

TcpClient tc =server.AcceptTcpClient();

這裏就一個同步接收的方式,那爲什麼說同步呢,因爲在這個端口下如果同是來了兩個客戶端請求,第一個連接得到響應,與服務端建立通訊,而第二個請求就會被一直阻塞直到第一個請求完成操作,各個請求之間就好像排個隊,順序執行,這就是同步。

異步呢,就是同時來兩個或者多個請求,服務端就同時響應多個客戶端,同時給他們連接。各個客戶端與服務器的通訊是並行的,一個客戶端不必等另一個客戶端完成操作。通常用這兩個方法來接收一個客戶端請求。

BeginAcceptTcpClient()

EndAcceptTcpClient()

//----------------------------------------------------------------------------------------------------------------------

最近練習一個程序 訂票客戶管理系統。用到TCP編程。

這個程序可以從用三種模式來完成。

1.阻塞模式(僅適合短連接)

這樣。

TcpListene server = new TcpListener(IPAddress.Parse("127.0.0.1"), port);

while(true)

{

               TcpClient tc =server.AcceptTcpClient();

              //  do ........................

}

來一個連接服務端端就響應了,然執行操作,如果操作沒完成再來一個客戶端請求就阻塞你,直到第一個請求完成操作。

總結特點:這種模式簡單易行,適合客戶端請求次數比較少場景。比如一下來了1000個請求,第一個去執行了 ,剩下的999個被阻塞。

2.多線程+阻塞模式(用於長連接和短連接)

TcpListene server = new TcpListener(IPAddress.Parse("127.0.0.1"), port);

while(true)

{

               TcpClient tc =server.AcceptTcpClient();

                //接收到客戶端請求之後 就起一個線程 負責這個客戶端TCP與服務端的通訊

               Thread  Th=new  Thread(F);

                Th.start();//有參數加參數沒參數不加

}

void  F( object  oo)

{

           //和客戶端進行通訊

}

想 這樣,一個請求來個,服務端響應然後給你一個線程負責和你的通訊。然後服務端又去響應其他客戶端的請求。而不必等待前一個連接是否完成操作。這樣模式由於 引入了多線程,就變成了異步操作就要考慮對臨界資源的互斥問題,就是讓多個線程訪問一個資源時候,去同步他們的操作。這裏不再說了。

在負責給客戶端的方法中 這裏我隨便寫了個F(object oo)如果關閉當前連接。就是異步的端連接, 如果不關就是異步的長連接。根據需要來確定。

總結特點:這種模式由於引入了多線程,提高了系統的效率,但是要考慮臨界資源的互斥問題,如何管理線程生命週期。

3 非阻塞模式

就不在用AcceptTcpClient()這種阻塞方式來接收請求。就是來一個請求馬上接收。

通常用這兩個方法組合使用

TcpListene server = new TcpListener(IPAddress.Parse("127.0.0.1"), port);

 server.Start();

 server.BeginAcceptTcpClient(new AsyncCallback(AcceptClient), server);

   void AcceptClient(IAsyncResult ar)
        {
            TcpListener server = (TcpListener)ar.AsyncState;
            TcpClient client = server.EndAcceptTcpClient(ar);
        }

當執行BeginAcceptTcpClient時候編譯器就會在線程池中創建一個線程監聽連接請求,如果有請求就會自動調用委託的方法(這裏的AcceptClient)來完成一個 TcpClient 的實例,再來一個客戶端請求,線程池又新建一個線程去實例一個TcpClient對象,當然瞭如果想做長連接的多客戶端與服務端的通訊時候,每一個TcpClient對象是要保存起來的,這只是異步的接收請求而已。

聽說做大型項目異步接收用的很多。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章