2013-03-07 91 views
0

我已經使用C#編寫了一個客戶端 - 服務器應用程序。爲什麼在客戶端分離TCP消息不起作用?

客戶端異步地發送消息使用4字節的報頭定義的消息大小,並且爲整個消息服務器等待(它知道的大小),然後引發一個事件DataReceived。當我異步發送和接收數據時,這一切都正常。

在某些時候,我想模擬接觸不良,其中2段使用Send()而不是BeginSend()

public void SendSyncString(string str, Commands cmd) 
    { 

     BinaryWriter bw = new BinaryWriter(new MemoryStream()); 
     bw.Write((int)cmd); 
     bw.Write((int)str.Length); 
     bw.Write(Encoding.ASCII.GetBytes(str)); 
     bw.Close(); 
     byte[] data = ((MemoryStream)(bw.BaseStream)).ToArray(); 
     bw.BaseStream.Dispose(); 
     SendSync(data,1); 

    } 

    public void SendSync(byte[] data,int delay) 
    { 
     //create |dataLength|data| segment 
     byte[] dataWithHeader = Combine(BitConverter.GetBytes(data.Length), data); 
     //send first block of data, delay, and then send the rest 
     socket.Send(dataWithHeader, 0, 4, SocketFlags.None); 
     Thread.Sleep(delay*1000); 
     socket.Send(dataWithHeader, 5, dataWithHeader.Length - 5, SocketFlags.None); 
    } 

工作發出一前一後。我希望明白爲什麼。 如果TCP只是一個字節流,並且沒有辦法知道每個分段何時到達,爲什麼我不能按照我的意願將它分成段,並且像上面那樣簡單地發送它們(假設前4個字節被完全發送)?

感謝您的見解。

+1

「這顯然不起作用」是你正面臨的問題的非常純粹的解釋...嘗試編輯你的文章,使其更具體。 – 2013-03-07 07:56:46

+0

同意。 「這不起作用」是什麼意思?你沒有收到消息?你沒有收到消息的第二部分?你的解析邏輯失敗了?還有別的嗎? – 2013-03-07 08:38:45

+0

我收到一封損壞的郵件,在閱讀selbie的回答後有意義。 – Daniel 2013-03-07 21:11:14

回答

4

因爲你的第一個電話socket.Send只派出4個字節:

socket.Send(dataWithHeader, 0, 4, SocketFlags.None); 

也就是說,在字節0,1,2偏移,和3被髮送(總共4個字節)。記住socket.Send的第三個參數是一個長度參數,而不是結束位置。

因此,該線有一個錯誤:

socket.Send(dataWithHeader, 5, dataWithHeader.Length - 5, SocketFlags.None); 

它發送字節偏離5,6,7 ..到數組的末尾。 它跳過了字節4.因此,接收器可能會阻塞,因爲接收完整的消息只有一個字節。

它應該閱讀:

socket.Send(dataWithHeader, 4, dataWithHeader.Length - 4, SocketFlags.None); 

你去那裏。

+0

這樣做... 謝謝 – Daniel 2013-03-07 09:36:46

1

我想模擬接觸不良,其中2段被送到一個其他

後,這不是一個「壞連接」。對於任何TCP連接的行爲來說,這是完全合法的方式。如果接收軟件無法正確處理,則寫入不正確。

假定前4個字節是完全

送你不能假設。

+0

非常有幫助。我會牢記這一點。謝謝 – Daniel 2013-03-07 21:10:15

相關問題