TCP套用編程

TCP套用編程

TCP是Transmission Control Protocol(傳輸控制協定)的簡稱,是TCP/IP體系中的面向連線的傳輸層協定,在網路中提供全雙工的和可靠的服務。

基本介紹

  • 中文名:TCP套用編程
  • 外文名:Transmission Control Protocol
  • 性質:傳輸控制協定
  • 簡稱:TCP
TCP套用編程簡介,異步TCP套用編程,異步操作方式,TCP編程各類提供的異步操作方法,EventWaitHandle類,AsyncCallback委託,TCP套用編程各種操作方法簡介,BeginAcceptTcpClient與EndAcceptTcpClient,BeginConnect與EndConnect,

TCP套用編程簡介

一旦雙方建立了TCP連線,連線中的任何一方都能向對方傳送數據並接收對方發來的數據。傳送數據時,程式設計師可以編寫程式不斷地將數據流寫入TCP的傳送緩衝區中,然後TCP自動從傳送緩衝區中取出一定量的數據流寫入TCP的傳送緩衝區中,然後TCP自動從傳送緩衝區中取出一定量的數據,將其組成TCP報文段逐個傳送給IP層,再通過IP層傳送出去。接收端從IP層收到TCP報文段後,將其暫時保存在接收緩衝區中,這時程式設計師就可以編寫程式依次讀取接收緩衝區中的數據,從而達到通信的目的。
利用TCP開發應用程式時,.NET框架提供兩種工作方式,一種是同步(Synchronous)工作方式,一種是異步(Asynchronous)工作方式。
同步工作方式是指利用TCP編寫的程式執行到傳送、接收或監聽語句時,在未完成工作前不再繼續下面的工作,即處於阻塞狀態,直到該語句完成相應的工作後才繼續執行下一條語句;異步工作則不論工作完成與否,都會繼續往下執行。例如:接收數據時,在同步方式下,接收方執行到接收語句後將處於阻塞方式,只有接收到對方發來的數據後才繼續執行下一條語句;而如果採用異步方式,則接收方執行到接收語句後,無論是否接收到對方的數據,程式都會繼續執行。
與同步工作方式和異步工作方式對應,利用Socket類進行編程時,系統也提供有相應的方法,分別稱為同步套接字編程和異步套接字編程。但是使用套接字編程比較複雜,涉及許多底層細節。為了簡化套接字編程,.NET框架又專門提供了兩個類:TcpClient類和TcpListener類。由於這兩個類與套接字一樣分別有各自的同步和異步工作方式及其對應的方法,在編程時,三個類都可以使用。因此為了簡化起見,無論使用哪個類,我們都從工作方式上將其稱為同步TCP和異步TCP,對應的編程方式就稱為同步TCP編程和異步TCP編程。
[ 注意:這裡的同步TCP與異步TCP僅僅是指工作方式,與執行緒間的同步不是一個概念。執行緒間的同步是指不同執行緒或不同執行緒使用的某些資源具有先後關聯的關係,它決定著邏輯執行順序。比如有A和B兩個資源,實際套用中要求只有對資源A處理後才能處理資源B,就說資源A與資源B存在同步關係。如果執行順序不正確就會引發錯誤。所以,執行緒間的同步關注的是一種邏輯關係。而同步TCP和異步TCP則僅僅指編程中採用哪種工作方式,即從執行到傳送、接收或監聽語句時,程式是否是繼續住下執行這個角度來說的。]
從邏輯關係上看,無論是同步TCP編程,還是異步TCP編程,在實際套用中既可能要求不同執行緒間同步,也可能不要求同步。

異步TCP套用編程

利用TcpClient和TcpListener在同步方式下接收、傳送數據及監聽客戶端連線時,在操作沒有完成之前一直處於阻塞狀態,這在接收、傳送數據量不大或者操作用時較短的情況下是比較方便的。但是,對於那些完成時間可能較長(如傳送大檔案)的任務時,使用同步操作可能就會造成系統假死,這種情況下,最好的辦法是使用異步操作。

異步操作方式

所謂異步操作方式,就是我們希望讓某個工作開始以後,能在這個工作尚未完成的時候繼續處理其他工作。
這裡舉一個是常生活的例子來說明:我們(主執行緒)安排A(子執行緒A)負責處理客人來訪登記工作,在同步方式下,如果沒有人來訪,A就只能一直呆在某個房間等待,而不能從事其他工作,顯然這種方式不利於並行處理。我們希望,沒有人來訪時,A不一定在這個房間等待,也可以到別處繼續做其他工作,而把等待這個工作交給總控室人員完成。這個總控室就是Windows系統本身,總控室如何及時通知A呢?可以讓A先告訴總控人員一個手機號F(callback需要的方法名F),以便有人來訪時可以立即給A打電話(通過委託自動運行F),A接到通知後,再回來處理客人來訪登記事務。
異步操作最大的優點是可以在一個操作沒完成之前進行其他操作。.NET框架提供一種稱為AsyncCallback(異步回調)的委託,該委託允許啟動異步的功能,並在條件具備時調用提供的回調方法(是一種在操作或活動完成時由委託自動調用的方法),然後在這個方法中完成並結束未完成的工作。
在異步操作方式下,每個Begin方法都有一個匹配的End方法。編寫程式時利用Begin方法開始執行異步操作,然後由委託在條件具備時調用End方法完成並結束異步操作。

TCP編程各類提供的異步操作方法


提供的方法
說明
TcpListener
BeginAcceptTcpClient
開始一個異步操作接受一個傳入的連線嘗試

EndAcceptTcpClient
異步接受傳入的連線,並創建新 TcpClient對像處理
TcpClient
BeginConnect
開始一個對遠程主機連線的異步請求

EndConnect
異步接受傳入的連線嘗試
Socket
BeginReceive
開始從連線的Socket中異步接收數據

EndReceive
結束掛起的異步讀取

BeginSend
將數據異步傳送到連線的Socket

EndSend
結束掛起的異步傳送

EventWaitHandle類

在現實工作中,有很多工作是相互的,某些工作必須等待另一個工作完成後才能繼續,這就是異步操作中的同步問題。在System.Threading命名空間中, 有一個EventWaitHandle類,用於在異步操作中控制執行緒的同步,即控制一個或多個執行緒繼續執行或等待其他執行緒完成。EventWaitHandle類可以讓作業系統通過發出信號完成多個執行緒間的同步,需要同步的執行緒可以先阻塞當前執行緒,然後根據Windows作業系統發出的信號,決定是繼續阻塞還是等待其他工作完成,還是不再等待而直接繼續執行。
EventWaitHandle類提供以下方法進行執行緒控制:
Reset方法:將信息狀態設定為非終止狀態,即不讓作業系統發出信號,從而使那些只能接收到信號才能繼續執行的執行緒處於阻塞狀態
Set方法:將事件狀態設定為終止狀態,這樣的等待的執行緒將會收到信號,從而由等待轉為繼續。
WaitOne方法:阻塞當前執行緒,等待作業系統發出信號,直到收到信號才解除阻塞。
作業系統發出信號的方式有兩種:
(1)發出一個信號,使某個等待信號的執行緒解除阻塞,繼續執行。
(2)發出一個信號,使所有等待信號的執行緒全部解除阻塞,繼續執行。

AsyncCallback委託

AsyncCallback委託用於引用異步操作完成時調用的 回調方法。在異步操作方式下,由於程式可以在啟動異步操作後繼續執行其他代碼,因此必須有一種機制,以保證該異步操作完成時能及時通過調用者。可以通過AsyncCallback委託實現這種機制。
異步操作的每一個方法都有一個Begin...方法和End...方法,程式調用Begin...方法時,系統會自動在執行緒池中創建對應的執行緒進行異步操作,從而保證調用方和被調用方同時執行,當執行緒池中的Begin...方法執行完畢時,會自動通過AsyncCallback委託調用在Begin...方法的參數中指定的回調方法。
回調方法是在程式中事先定義的,在回調方法中,通過End...方法獲取Begin...方法的返回值和所有輸入/輸出的參數,從而達到完成參數傳遞的目的。

TCP套用編程各種操作方法簡介

BeginAcceptTcpClient與EndAcceptTcpClient

BeginAcceptTcpClient和EndAcceptTcpClient方法包含在System .Net.Sockets命名空間下的TcpListener類中。
在異步TCP套用編程中,服務端可以使用TcpListener類提供的BeginAcceptTcpClient方法開始接收新的客戶端連線請求。在這個方法中,系統自動自用執行緒池創建需要的執行緒,並在操作完成時利用異步回調機制調用提供給它的方法,同時返回相應的狀態參數。其方法原型為:
public IAsyncResult BeginAcceptTcpClient(AsyncCallback callback,Object state)
其中:參數1為AsyncCallback類型的委託;參數2為Object類型,用於將狀態信息傳遞給委託提供的方法。
例如:AsyncCallback callback=new AsyncCallback(AcceptTcpClientCallback);
tcpListener.BeginAcceptTcpClient(callback,tcpListener);
程式執行BeginAcceptTcpClient方法後,立即在執行緒池中創建需要的執行緒,同時在創建的執行緒中監聽客戶的連線需求。一旦接受了客戶端的連線請求,就自動通過委託執行相應的方法,並返回狀態信息。例子中我們將此方法命名為AcceptTcpClientCallback,狀態信息為TcpListener類型的實例tcpListener。
定義異步回調方法的格式:
void AcceptTcpClientCallback(IAsyncResult ar){ 回調代碼 }
[ 註:回調方法中的參數只有一個,必須是實現報IAsyncResult類型的接口,它表示異步操作的狀態。]
在回調方法中,必須調用EndAcceptTcpClient方法才能完成客戶端連線,關鍵代碼如下:
void AcceptTcpClientCallback(IAsyncResult ar){
......
TcpListener myListener=(TcpListener)ar.AsyncState;
TcpClient client=myListener.EndAcceptTcpClient(ar);
......
}
程式執行EndAcceptTcpClient方法後,會自動完成客戶端連線請求,並返回包含底層套接字的TcpClient對象,接下來我們就可以利用這個對象與客戶端進行通信了。
默認情況下,程式執行BeginAcceptTcpClient方法後,在返回狀態信息前,不會像同步TCP方式那樣阻塞執行緒等待用戶連線,如果我們希望在返回狀態信息前阻塞當前執行緒,就要調用ManualResetEvent對象的WaitOne方法。

BeginConnect與EndConnect

BeginConnect 方法和EndConnect方法包含在命名空間System. Net.Sockets下的TcpClient類和Socket類中,這裡我們只討論TcpClient類中的方法。
在異步TCP應用程式編程中,BeginConnect方法通過異步方式向遠程主機發出連線請求,有三種重載形式,方法原型為:
public IAsyncResult BeginConnect(IPAddress address,int port,AsyncCallback requestCallback,Object state);
public IAsyncResult BeginConnect(IPAddress[] addresses,int port,AsyncCallback requestCallback,Object state);
public IAsyncResult BeginConnect(string host,int port,AsyncCallback requestCallback,Object state);
其中address為遠程主機的IPAddress對象;port為遠程主機連線埠號;requestCallback為AsyncCallback類型的委託;state為包含連線操作的相關信息,當操作完成時,此對象傳遞給requestCallback委託。
在BeginConnect方法操作完成前,調用該方法的執行緒不會阻塞,系統會自動調用獨立的執行緒來執行該方法,直到與遠程主機連線成功或拋出異常。如果希望在調用BeginConnect方法之後阻塞執行緒,可以調用ManualResetEvent對象的WaitOnet方法。
異步BeginConnect方法也只有在調用了EndConnect方法之後才算執行完畢,因此程式中需要在提供給requestCallback委託調用的方法中調用TcpClient對象的EndConnect方法。關鍵代碼為:
......
AsyncCallback requestCallback=new AsyncCallback(RequestCallback);
tcpClient.BeginConnect(遠程主機IP或域名,遠程主機連線埠號,requestCallback,tcpClient);
......
void RequestCallback(IAsyncResult ar){
......
tcpClient=(TcpClient)ar.AsyncState;
client.EndConnect(ar);
.......
}

相關詞條

熱門詞條

聯絡我們