TDI客戶在不同的節點彼此傳送接收連線導向數據必須要建立一個點對點的連接。在傳輸數據之前,每一個客戶必須做以下的事情:
- 開啟一個傳輸位址( transport address)。
- 開啟一個連接端點(connection endpoint)。
- 關聯開啟的傳輸位址與連接端點。
- 建立彼此之間的點對點連接,一個負責發起連接請求,其他負責接收這個請求。
實際上,一旦本地節點傳輸對遠端節點傳輸發送一個連結接受偵(connection-acceptance frame),則接收連結請求的客戶就可以接受來自於遠端節點的數據。
在透過底層傳輸完成點對點連線以後,客戶端彼此之間可以跨過網路傳送數據。
Sending Data on an Endpoint-to-Endpoint
Connection
下圖示範一個核心模式的客戶如何在一個點對點連接之間發送數據。
本地端節點的TDI客戶發布一個發送(send)請求,要求本地傳輸從連結端點發送一筆數據至遠端的連結端點。要做到這個,本地端節點的客戶會提交一個 TDI_SEND 的控制請求給他的底層傳輸。客戶端可以使用 TdiBuildSend 來包裝這個IRP,並且裡面包含了一個客戶端提供的緩衝區指標,其內容包含一個stream-oriented 或是message-oriented 的TSDU。這個緩衝區的最大長度只要在TDI傳輸允許的範圍之內就可以。如果傳輸支援快速發送(expedited sends),則客戶可以請求發布一個快速數據,這個請求會排在傳輸驅動佇列(queue)中其他已經在等待傳送的普通發送(normal sends)請求之前優先來處理。如果傳輸驅動支援內部緩衝,則客戶可以發布一個非阻塞(nonblocking)發送請求。
客戶調用 IoCallDriver 轉發TDI_SEND的IRP到底層傳輸的TdiDispatchInternalDeviceControl例程。這個例程會檢查MinorFunction 並更進一步地的調用內部的發送函式來處理這個IRP。發送請求,如果客戶已經提交其他的發送請求,並且這些請求還沒被處理,則內部驅動函式會將這個新的發送請求放置佇列當中。傳輸總是將快速請求數據排在正常的TSDUs之前處理。而無論是普通或是快速,都是使用FIFO的順序來發送客戶端要求的命令。在傳輸完成每一個客戶提交的TDI_SEND IRP之前,傳輸也會複製客戶提供的數據到內部緩衝區或是在網路中發送指定的數據。
如果底層傳輸的內部緩衝區不足,導致一個非阻塞(nonblocking)發送請求失敗。則當傳輸驅動有可用的緩衝區位置可以傳輸時,傳輸驅動會調用客戶註冊的 ClientEventSendPossible 處理函式, 通知客戶可以重新提交一個TDI_SEND的請求。
Receiving Data on an Endpoint-to-Endpoint
Connection
下圖示範一個核心模式的客戶如何在點對點連接之間接收數據。
無論是普通(normal)或是快速(expedited),在兩端節點連線的情況下,本地端節點可以透過發送 TDI_RECEIVE 請求給底層傳輸來接收一個TSDU。客戶端可以使用 TdiBuildReceive 來封裝這個IRP,其內包含了客戶端提供的緩衝區位址(接收來自於傳輸端複製全部或是部分TSDU的數據)。緩衝區的長度可以是TDI傳輸驅動所允許的範圍之內。
客戶端調用IoCallDriver來轉發TDI_RECEIVE IRP給底層傳輸TdiDispatchInternalDeviceControl例程。此例程會檢查MinorFunction 並且更進一步的調用內部函式來處理這個IRP。內部驅動會不間斷地轉移接收到的數據到客戶端所提供的緩衝區直到緩衝區收滿或是接收的TSDU枯竭。
然而,在接收操作期間,快速(expedited)數據的優先權高於普通(normal)數據。如果一個快速TSDU從一個遠端節點進入,而此時傳輸正在處理一個客戶提交的普通數據接收請求。則無論有多少普通的TSDU數據已經轉移到客戶端提供的緩衝區,傳輸端都會完成這個客戶端的IRP請求,接者,傳輸端會處理快速數據接收直到命令完成,而客戶端必須發布其他的TDI_RECEIVE來獲得剩餘的普通TSDU數據。
客戶端事件處理程序在稍後會複製數據。如果ClientEventReceive或是ClientEventReceiveExpedited沒有接收到所有的數據,他可以做以下的事情:
- 立即返回未接受(not-accepted)的狀態,清楚的告知底層傳輸這個接收到的TSDU是客戶端不感興趣的。
- 建立其他的TDI_RECEIVE接收請求來獲得剩餘的TSDU數據。
- 依靠後續的驅動接收事件通知來獲得剩餘的數據。
底層傳輸驅動程式總是賦予ClientEventChainedReceive與ClientEventChainedReceiveExpedited 處理程序僅讀取(read-only)完整TSDU的權限。因此,這些例程不需要發布一個 TDI_RECEIVE 的請求到底層傳輸,或是處理部分接收的TSDUs。然而,TDI客戶端驅動程式負責立即的調用TdiReturnChainedReceives來返回相關聯的資源(初始由NDIS微阜驅動所配置)。