2016年10月4日 星期二

TDI Operations - VII

Sending and Receiving Connectionless Data

一旦核心模式的客戶端成功對底層傳輸開一個傳輸位址(transport address),他就可以在網路上使用無連線通信(connectionless communication)的方式傳輸數據。

要使用這種方式接收數據,客戶端必須向他的底層傳輸註冊它的ClientEventReceiveDatagram或者是明確的對底層傳輸發布一個TDI_RECEIVE_DATAGRAM請求。

更多有關開一個傳輸位址以及對指定的位址註冊一個事件處理函式,可以參考 Opening a Transport Address.

Sending a Datagram

下圖示範一個TDI客戶如何發送一個數據報(datagram)到遠端節點。


如本圖所示,發送一個數據報類似於發送一個連線導向的數據。然而,本地端節點客戶對於一個開的傳輸位址提交一個TDI_SEND_DATAGRAM請求,這取代了一個點對點連線上的發送方式。

一個TDI_SEND_DATAGRAM IRP請求底層傳輸發送一個客戶端提供的數據報到一個特定位址上的一個未知數量的遠端節點客戶。

本地端客戶可以使用TdiBuildSendDatagram來封裝這個請求。隨著目標的遠端節點位址,客戶端可以提供任何大小的緩衝區數據(在傳輸端允許範圍之內)。客戶端可以透過詢底層傳輸來確定這個長度限制,這在 Setting and Querying Information已經有介紹過了。

Receiving a Datagram

下圖示範了一個核心模式的客戶如何從它的底層傳輸接收一個來自於遠端節點的數據報(datagram)

如本圖所示,接收一個數據報類似於接收一個連線導向數據。然而,本地端節點客戶對於一個開啟的傳輸位址提交一個TDI_RECEIVE_DATAGRAM請求,這取代了一個點對點連線上的接收方式。

然而,客戶端可以接收來自於遠端節點所發送的數據報(此遠端節點位址是由本地客戶所開啟的傳輸位址作為數據報的目的地)。其它本地端客戶只要開啟相同的傳輸位址都可以接收相同的數據報。

一個TDI_RECEIVE_DATAGRAM IRP請求底層傳輸回傳一個來自於遠端節點的數據報。本地節點客戶可以使用TdiBuildReceiveDatagram來封裝這一個請求。隨著一個表示為開啟傳輸位址的檔案物件,客戶提供TDI傳輸驅動一個緩衝區(TDI傳輸所允許接收長度範圍之內)。由於TDI傳輸絕不會分段數據報,所以本地端節點客戶通常會發布一個接收數據報請求(receive-datagram request)來接收一個數據報。

當完成這樣一個請求時,傳輸驅動會複製一份接收的數據報到客戶所提供的緩衝區,並且會回傳遠端節點這個IRP已經完成。如果收到的數據報超出緩衝區大小,則傳輸會切斷超出的數據。

當完成這樣一個請求時,傳輸驅動會複製一份接收的數據報到客戶所提供的緩衝區,並且會回傳遠端節點這個IRP已經完成。如果收到的數據報超出緩衝區大小,則傳輸會切斷超出的數據。

客戶端也可以透過底層TDI傳輸驅動的事件通知來接收遠端的數據報。對於這些通知事件,傳輸驅動會移除TSDU的檔頭(來自遠端節點),並且調用客戶端所註冊的ClientEventReceiveDatagram或是ClientEventChainedReceiveDatagram處理函式。ClientEventReceiveDatagram可以執行下列操作之一:
  • 立即回傳一個未接受(not-accepted)的狀態,並且明確的告知傳輸驅動這個TSDU不是客戶端有興趣的。
  • 如果傳輸僅提供部分的數據,則複製部分數據到內部緩衝區並封裝一個TDI_RECEIVE_DATAGRAM來請求剩餘的TSDU數據,接著回傳控制權。
  • 複製所有的TSDU到內部緩衝區並回傳控制權。

如果客戶端沒有複製數據或是回傳一個IRP,則非緩衝(Nonbuffering)傳輸驅動可以在接收數據報事件指示後丟棄數據。緩衝式的傳輸驅動則會保留一定數量的數據報訊息,讓它的客戶可以在稍後透過明確的TDI_RECEIVE_DATAGRAM請求來重新獲得數據。

透過底層傳輸,ClientEventChainedReceiveDatagram處理函式總是獲得僅讀取(read-only access)完整TSDU的權限。隨後,這個例程不需要發布一個TDI_RECEIVE_DATAGRAM請求到底層傳輸。然而,客戶端負責立即的調用 TdiReturnChainedReceives 來回傳由NDIS微阜驅動所配置的資源。

沒有留言:

張貼留言