2010-01-09 70 views
3

我是編程新手,我對異步套接字編程感到困惑。C#異步套接字BeginSend EndReceive

例如,假設我有兩個BeginSend s,一個接一個。第一個發送一百萬個字符,第二個發送只有64個字符。

由於異步性不會在第一個完成之前完成第二個BeginSend

如果是的話我怎麼能告訴接收到的數據在EndRecieve,屬於哪個消息?

回答

7

你真的不應該兩次調用BeginSend。 我認爲如果發生這種情況,你最終會看到拋出的異常。

您必須在調用另一個BeginSend之前調用EndSend。這通常在回調函數中完成。

請查看MSDN上的示例Using an Asynchronous Client Socket。在回調中調用EndSend,然後設置一個名爲「sendDone」的ManualResetEvent。這是線程間通信的一種形式,其中回調會向主線程發送異步發送已完成的信號。這樣可以讓你的程序確定下一部分數據。從你的主線程

  • 呼叫BeginSend發送第1,000,000字節
  • 你的主線程可以檢查一個信號量或類似ManualResetEvent的東西觸發它發送下一個64個字節。您的其他選項是使用隊列來發送數據
  • 當數據完成發送時,您傳遞給BeginSend的回調將被調用。
  • 在此回調中,您將調用EndSend。按照這個設置ManualResetEvent,或者想要使用什麼樣的線程間觸發器。

我記得曾經做過的最簡單的選項是調用BeginSend來獲取第一部分數據的回調中的下一條數據。

例如

int NumBytesSent; // member variable containing how many bytes you have sent so far 
string Message; // Message to send that is large 

當你調用BeginSend,在經過了一大塊說100個字節(挑選更高效的傳輸數量較多,但不是太大)由100 下發送和增量NumBytesSend,在你的回調先前的發送完成後,您可以檢查NumBytesSent < Message.Length,然後是否發送下一個消息塊。

這是如何發送一個文件,您一次發送一堆字節,並只是不斷髮送文件的塊,直到它全部發送。

我強烈建議製作一個簡單的客戶端/服務器來執行類似於通過連接發送完整文件的操作。同時在網上查看MSDN文檔和許多其他的例子。

獲取有關這個良好的抓地力會幫助你與很多其他的C#主題爲異步方式運行(或使用委託/回調)是很常見的.NET

+0

+1調用下一個BeginSend,建議先建立簡單的建議。 –

+1

感謝馬克,這是我一直建立我的網絡代碼的方式。 我已經做了很多次這樣的事情,但總是從一個通用的簡單起點開始,然後從那裏開始工作。 – Fuzz

+0

有人可以解釋它們的含義:它假設一個名爲connectDone的全局ManualResetEvent。 – Eidenai

1

BeginSend method包括參數AsyncCallback callback。如果你使用兩個不同的回調函數,你可以先看看哪一個回調函數完成。

但是,如果您試圖在同一連接上發送這兩個消息,您將遇到問題。在發送第二條消息之前,您應該等到第一條消息完全發送完畢。

+0

是IM發送兩個消息到相同的地址/端口。 – iTEgg

+0

我認爲發送可能會起作用,但我懷疑這些消息會變成交織和不可解析的。 –

+0

這個問題。我如何避免這種情況?它可以做到,因爲像mirc這樣的應用程序一直處理這些類型的問題。我想知道我該如何執行它? – iTEgg