2016-07-01 76 views
0

我正在維護一個C#系統,其部分工作是從隨機客戶端接收tcp消息(使用socket.recv())。我們有一個消息協議,這樣外人開發人員可以填寫格式良好的消息。我如何收到消息

郵件格式如下:

{ public data(fixed length):private data(variable length) } 

要接收的消息,我們需要一個私有數據長度字段在此消息,但有人需要發送,可能有填寫錯誤長度一個number.How消息我能滿足這種需求嗎?

這裏是我的代碼:

public static int ReceiveMessage(int totalByteNumber, Socket socket, byte[] recvBuffer) 
{ 
    try 
    { 
    int offset = 0; 
    do 
    { 
     try 
     { 
     int num = socket.Receive(recvBuffer, offset, totalByteNumber - offset, SocketFlags.None); 
     if (num == 0) 
     { 
      throw new ApplicationException(); 
     } 
     offset += num; 
     } 
     catch (SocketException ex) 
     { 
     if (ex.SocketErrorCode == SocketError.IOPending || ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable) 
      Thread.Sleep(30); 
     else if (ex.SocketErrorCode == SocketError.WouldBlock) 
     { 
      socket.Blocking = true; 
      Thread.Sleep(30); 
     } 
     else 
     { 
      LogManager.WriteError("Origin IP:" + (object) ((IPEndPoint) socket.RemoteEndPoint).Address); 
      throw ex; 
     } 
     } 
    } 
    while (offset < totalByteNumber); 
    return offset; 
    } 
    finally 
    { 
    SocketUtility.LogMessage("Recv", recvBuffer, socket); 
    } 
} 
+0

只要你不能看完整的消息返回錯誤。消息必須格式正確並且填寫完整。 – BWA

+0

你是對的,但那是關於公司政治......所以我只是想知道,從技術上講,是否有解決方案? –

+0

你可以從端口讀取給定的字節,嘗試解析信息,如果太短,讀取更多,與prev讀取合併,並嘗試找到結束消息。 – BWA

回答

0

無法容納格式不正確的消息,至少不可靠。 TCP不保留消息邊界,因此您無法知道發送給您的消息的時間長短。

實際上,如果您通常有短的請求,並且請求者在一個發送系統調用中發送整個請求,那麼每次接收很可能只返回一個請求消息,但這不可靠。例如,如果請求者將您連續發送給您兩個,那麼在您的流程安排完成之前,它們可能會進行合併,以便在一次接收呼叫中將兩者都返回給您。

您的選擇:

  • 消息中的長度字段告訴你多少期待(大多數二進制協議以這種方式工作)
  • 一些標誌圖案消息(空字節,或空行文本或任何;基於文本的協議,如HTTP通常以這種方式工作)
  • 文件結束(即呼叫者可以發送請求,然後調用socket.Shutdown(Send);,你會得到EOF,並知道這一切都期望;顯然是這種方式的一次性交易)
+0

謝謝。很有幫助。 –