2016-08-03 12 views
1

Ich habe einen TCP-Server geschrieben, in dem die Anzahl der zu lesenden Bytes im Header mit zwei Bytes vorangestellt ist. Nach dem Lesen aus dem Stream und dem Zurücksenden der Antwort an den Client werden sowohl NetworkStream als auch TcpClient entfernt. Das Problem ist, dass der Client meine Antwort nicht zu erhalten scheint, wenn ich die Thread.Sleep() Zeile nicht auskommentiere. Hier ist der Code:NetworkStream Sleep() Problem

using (var tcpClient = await tcpServer.AcceptTcpClientAsync()) 
{ 
    tcpClient.NoDelay = true; 

    using (var stream = tcpClient.GetStream()) 
    { 
     var twoBytesHeader = new TwoByteHeader(); 
     var headerBuffer = new byte[twoBytesHeader.HeaderLength]; 

     using (var binaryReader = new BinaryReader(stream, Encoding.ASCII, true)) 
     { 
      headerBuffer = binaryReader.ReadBytes(twoBytesHeader.HeaderLength); 

      int newOffset; 
      var msgLength = twoBytesHeader.GetMessageLength(headerBuffer, 0, out newOffset); 

      var buffer = binaryReader.ReadBytes(msgLength); 

      string msgASCII = Encoding.ASCII.GetString(buffer); 

      var bufferToSend = await ProcessMessage(msgASCII); 

      using (var binaryWriter = new BinaryWriter(stream, Encoding.ASCII, true)) 
      { 
       binaryWriter.Write(bufferToSend); 
       binaryWriter.Flush(); 
      } 

      //Thread.Sleep(1000); 
     } 
    } 
} 

Wenn Schlaf unkommentiert ist, der Kunde erhält Antwort und zeigt dann an, dass die Client-disconected hat. Ich kann den Grund dieses Verhaltens nicht herausfinden

+0

Wenn Sie sicher sein müssen, dass beim Senden Ihrer Daten kein Fehler aufgetreten ist, dann ist async möglicherweise nicht die richtige Antwort, Sie möchten es senden, wissen, dass es gesendet wurde und dann schließen? – BugFinder

+0

Vielen Dank für die Antwort. In diesem Fall erwarte ich WriteAsync, so dass es warten wird, bis alle Bytes gesendet sind und erst dann die Verbindung schließen. Es muss noch etwas anderes geben, was ich falsch mache. – GAG

Antwort

2

Sie gehen davon aus, dass ein Lesevorgang so viele Bytes lesen, wie Sie angegeben haben. Stattdessen wird mindestens ein Byte gelesen. Ihr Code muss damit umgehen können. BinaryReader.ReadBytes können Sie eine genaue Anzahl von Bytes lesen und einige Ihrer Boilerplate Code loswerden.

Auch sollten Sie wahrscheinlich nicht ASCII-Codierung verwenden, die die schlechteste Codierung ist.

+0

Vielen Dank, dass Sie auf das mögliche Problem beim Lesen mit Stream hingewiesen haben. Ich werde das berücksichtigen. Was die Codierung angeht, habe ich keine andere Wahl, da der Client ASCII-codierte Nachrichten sendet. Wie auch immer, ich kann immer noch nicht herausfinden, warum das Setzen von Sleep() nach stream.Flush() den Client dazu bringt, eine Antwort zu erhalten. Ich habe über Nagles Algorithmus gelesen, aber ich gehe davon aus, dass Flush sich ähnlich verhält, als hätte ich die NoDelay-Eigenschaft festgelegt. – GAG

+0

Vielleicht ist der Client defekt? Sende den Code .; Das Problem, das ich beschrieben habe, kann dazu führen, dass der Server abstürzt und keine Vertrauensstellung sendet. Also solltest du das sowieso beheben und den neuen Code posten. Flush auf einem NetworkStream macht nichts. Es kann nichts ändern. – usr

+0

Das Problem ist, dass der Client eine externe Anwendung ist, auf die ich keinen Zugriff habe. Ein einfacher Client, den ich zum Testen geschrieben habe, funktioniert einwandfrei. Ich werde Änderungen vornehmen, die Sie vorgeschlagen haben, und sehen, ob es hilft, danke – GAG