2010-01-03 73 views
1

我想要一些幫助以下。這與異步套接字有關。C#void ReceiveData(IAsyncResult iar)

從發件人:

string stringData = "Welcome to my server server server"; 
byte[] message1 = Encoding.ASCII.GetBytes(stringData); 

//MessageBox.Show(message1.Length.ToString()); 

client.BeginSend(message1, 0, message1.Length, SocketFlags.None, new AsyncCallback(SendData), client); 

這裏可以看出,該message.length可以找到。

- 在客戶端上

Socket remote = (Socket)iar.AsyncState; 
    int recv = remote.EndReceive(iar); 
    string stringData = Encoding.ASCII.GetString(data, 0, recv); 

我的問題是有沒有訪問發送的數據的實際長度,並基於該呼叫收到數據的方式,直到完整的消息被收到?

回答

7

否 - TCP/IP是協議。僅僅因爲你用一次呼叫發送數據並不意味着它將作爲一個數據包發送,或者它不會與其他數據包合併。換句話說,發送「X」然後發送「Y」相當於發送「XY」 - 它們可能以完全相同的數據包進行傳輸,與另一端無法區分。

如果您想在流中使用單個「消息」,您應該在數據前加上幾個字節來明確指出其長度。 (另一種方法是使用分隔符,但我更喜歡使用長度前綴 - 這樣可以更容易地知道您還需要接收多少數據,您無需擔心開始使用下一條消息,你不必擔心以某種形式逃避分隔符。)

+0

而不是前綴我剛剛實現了一個循環,如此處所述http://stackoverflow.com/questions/582550/c-begin-endreceive-how -DO-I-讀大的數據。它似乎在工作! :) – iTEgg 2010-01-03 16:40:12

+0

如果您希望在套接字關閉之前接收所有數據,那麼您只能保持循環,否則當您*實際*看到它時,您將無法知道。如果您只是在連接上執行單個請求/響應,那很好,但它不適用於每個方向都有多個消息的「對話」協議類型。 – 2010-01-03 16:48:29

0

只有當傳送某些信息來傳達長度時 - 或者將消息的長度預先保留,或者發送某種類型的終止符字符。