[英]Split messages over tcp
我在uni項目中遇到了一些麻煩。 我從C ++客戶端向C#服務器發送tcp消息,服務器分兩部分接收它。 有可能阻止它下來嗎? 我輸出在我的客戶端發送的數據,所有數據都是1件,所以它不能這樣。 這是我的OnReceiveData方法:
void OnReceiveData(IAsyncResult result){
try{
int readbytes = myStream.EndRead(result);
if (readbytes <= 0){
//client is not connected to the server anymore
CloseSocket();
return;
byte[] newBytes = new byte[readbytes];
Buffer.BlockCopy(readBuff, 0, newBytes, 0, readbytes);
myStream.BeginRead(readBuff, 0, readbytes, OnReceiveData,
null);
string output =
System.Text.Encoding.ASCII.GetString(newBytes, 0,
readbytes);
Text.WriteLog(output);
ServerHandleData.HandleData(connectionID, newBytes);
}
catch (Exception e)
{
Text.WriteError("Error Code: " + e);
CloseSocket();
}
}
謝謝!
沒有辦法“阻止它”,這就是流式 TCP的工作方式。
簡而言之,由於TCP是流式傳輸,因此沒有消息邊界。 它只是一個連續的字節流。
要在數據之間實現某種消息傳遞或邊界,那么您需要提出自己的應用層協議來放在TCP之上。 例如,您可以引入某種消息邊界令牌,特殊字符,字節或字符/字節序列,這意味着當前消息已結束。 或者您可以發送包含實際消息數據大小的固定大小的消息頭。
然后在接收時需要在循環中接收,直到您檢測到消息結束。 為此,最簡單的方法是使用數據長度的固定大小的標頭,然后您只需嘗試讀取(標頭或數據的)長度,減少接收每次迭代的字節數,直到沒有更多接收(接收的字節數達到零)。
不,TCP是流,而不是單個“數據塊”。
如EndRead示例所示 ,消息可以在多個部分中讀取,因此您必須讀取這些部分並將它們連接起來。
readbytes = myStream.EndRead(result);
myCompleteMessage = String.Concat(myCompleteMessage,
Encoding.ASCII.GetString(myReadBuffer, 0,
readbytes));
// message received may be larger than buffer size so loop through until you have it all.
while(myStream.DataAvailable) {
myStream.BeginRead(myReadBuffer, 0, myReadBuffer.Length,
new AsyncCallback(NetworkStream_ASync_Send_Receive.myReadCallBack),
myStream);
}
所以一段時間后我設法修復它。 問題是開始讀取中的讀取字節被設置為先前的消息長度,這迫使它拆分消息。 我通過手動設置大小來修復它。
謝謝你們的建議! :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.