2016-07-01 8 views
0

Ich führe ein C# -System, ein Teil dessen Job empfängt TCP-Nachrichten von zufälligen Clients (mit socket.recv()). Wir haben ein Nachrichtenprotokoll, damit Außenseiter-Entwickler gut formatierte Nachrichten füllen können.Wie kann ich eine Nachricht erhalten

Nachrichtenformat wie folgt:

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

Nachricht empfangen zu können, benötigen wir ein privates Datenlängenfeld in dieser Nachricht, aber jemand braucht eine Nachricht zu senden, die in falsch Länge füllen können number.How Kann ich diese Nachfrage erfüllen?

Hier ist mein Code:

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

Einfach, wenn Sie nicht den vollen Nachrichtenrücklauffehler lesen können. Die Nachricht muss gut formatiert und ausgefüllt sein. – BWA

+0

Sie haben Recht, aber das ist die Unternehmenspolitik .... Ich frage mich also, technisch gibt es eine Lösung dafür? –

+0

Sie können die angegebenen Bytes vom Port lesen, parsen Sie msg und wenn zu kurz, lesen Sie mehr, fusionieren Sie mit prev read, und versuchen Sie, die Endnachricht zu finden. – BWA

Antwort

0

Sie nicht falsch formatierte Nachrichten aufnehmen kann, zumindest nicht zuverlässig. TCP behält keine Nachrichtengrenzen bei, daher können Sie nicht wissen, wie lange die Nachricht an Sie gesendet wurde.

In der Praxis, wenn Sie in der Regel kurze Anfragen haben und der Anforderer die gesamte Anfrage in einem senden Systemanruf sendet, besteht eine gute Chance, dass jeder Empfang genau eine Anfrage Nachricht zurückgibt, aber das ist nicht zuverlässig. Wenn der Anforderer Ihnen beispielsweise zwei Back-to-Back-Nachrichten sendet, werden diese möglicherweise vor dem geplanten Vorgang zusammengeführt, sodass beide in einem einzigen Empfangsaufruf an Sie zurückgegeben werden können.

Ihre Optionen:

  • in der Nachricht ein Längenfeld sagen Ihnen, wie viel zu erwarten (die meisten binäre Protokolle arbeiten auf diese Weise)
  • einige Flaggenmuster in der Nachricht (null Byte oder leere Zeile von Text oder was auch immer; Text-basierte Protokolle wie HTTP funktionieren oft auf diese Weise)
  • Ende der Datei (dh Anrufer könnte eine Anfrage senden, dann socket.Shutdown(Send); aufrufen, würden Sie EOF bekommen und wissen, dass alles zu erwarten ist; offensichtlich a One-Shot-Deal auf diese Weise)
+0

Danke. Sehr hilfreich. –