2017-01-04 29 views
18

在Mono 3.12上,我使用Socket.SendAsync(SocketAsyncEventArgs)和TCP流Socket來實現基於請求的流式協議。我使用SocketAsyncEventArgs.BufferList來設置多個數據緩衝區。完成TCP Socket SendAsync操作而不傳輸BufferList中的所有字節?

在爲SocketSocketAsyncEventArgs的文檔,我無法找到的是否爲SocketAsyncEventArgs.Completed,而不當使用BufferList發送的所有字節,使我們必須驗證對SocketAsyncEventArgs.BytesTransferred的印象中引發的任何提及。

在另一方面,Socket.BeginSend使得這樣的保證

當應用程序調用BeginSend,該系統將使用 單獨的線程執行指定的回調方法,並將 塊EndSend直到Socket發送請求的字節數 或引發異常。

不規範作出關於使用SendAsyncSocketAsyncEventArgs.BufferList時傳輸的字節數是什麼保證?

假設事件已完成SocketError.Success

+1

我想問題是:「SocketAsyncEventArgs.Completed'處理程序是否可以在沒有套接字錯誤和'e.BytesTransferred!= length'的情況下被調用?」從我可以在.NET框架下收集是不可能的:http://stackoverflow.com/questions/28675811/when-i-call-wsasend-will-all-the-data-be-sent和http:// stackoverflow .com/questions/14347708/calling-wsasend-in-completion-port – jorgebg

+0

你能提供一些測試代碼嗎? –

+0

@DieterMeemken你需要測試什麼來回答_規範做了什麼保證?正如我所提到的,我將'SendAsync'與'SocketAsyncEventArgs'一起使用並設置了一個'BufferList'。 –

回答

1

當使用帶有SocketAsyncEventArgs.BufferList的SendAsync時,規範對傳輸的字節數有什麼保證?

首先,可以針對錯誤引發事件,在這種情況下,您可以假設並非所有字節都已傳輸。爲此,您需要爲SocketError.Success測試SocketAsyncEventArgs.SocketError。另外,如果你引用'規範',我假設你的意思是(Microsoft)Windows套接字文檔(因爲你鏈接到這個SendAsync和其他描述)。

爲了確定文檔中說明或暗示了在成功完成事件調用時傳輸的字節數,我們必須執行幾個步驟。第一步是查看SendAsync是否使用重疊I/O。該問題在Overlapped Input/Output文檔中得到解答。該機制的實現對底層傳輸提供程序是強制性的,因此它是唯一保證可用於Windows套接字的重疊I/O機制。因此,SendAsync保證使用具有WSA_FLAG_OVERLAPPED屬性的套接字。

請注意,對SendAsync reference implementation的檢查表明SendAsync的確在使用帶有重疊I/O的WSASend,但這僅僅是一種觀察。

第二步是確定什麼重疊的I/O告訴我們有關已完成事件的信號傳遞與傳輸的字節數有關。在幾個地方描述了這種情況,例如在這個Overlapped I/I and Event Objects頁面:當發送緩衝區被消耗時將會提供「指示」。在[WSASend]函數的註釋部分中給出了更多的細節:'完成指示將發生,調用完成一個例程或設置一個事件對象,當緩衝區被傳輸' 。

這仍然留下一些空間來準確解釋這個短語。基本上它說數據被套接字範圍之外的底層傳輸機制所接受和證實。這並不一定意味着它已經到達遠程端點協議層,這取決於通信協議。對於TCP流套接字,我會推斷它表示數據已到達遠程端點。

此處的結論是,文檔保證(對於非錯誤情況)SendAsync已完成事件僅在所有字節已傳輸時發生。

+0

是的,讓我們假設只有'SocketError.Success'。我會編輯我的問題。我不相信。當我鏈接到文檔時,我的意圖是鏈接到.Net標準庫,應該由所有.Net運行時實現,而不僅僅是Windows。 Windows的實現可以做到這一點,但這是唯一正確的方法嗎? –

-1

你想在這裏檢查什麼?你是否擔心在發送所有字節時你沒有收到所有字節?

當您一次發送100個字節並嘗試在另一端讀取100個字節時,並不保證您將一次接收所有字節。它可以分成100個1字節的數據包。這就是TCP的工作原理。您始終需要累積字節,然後形成並分隔您的數據包。這就是所謂的TCP套接字管道工作。 WCF和所有這些包裝爲你做。