Autor Beitrag
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6386
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Fr 16.06.06 08:41 
Zuerst mal ein bisschen Source:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
    public string SendCommand(string Command)
    {
      string ReturnResult = string.Empty;
      int countReceive = 0;
      
      try
      {
        // Client-StreamReader
        srClient.DiscardBufferedData();
        // interner Log-Eintrag
        LogEntry(Command);
        // Client-StreamWriter
        swClient.WriteLine(Command);
        // Schleife die warten Soll, bis alle Daten verfügbar sind
        do
        {
          // Wieviel ist beim tcpClient verfügbar?
          countReceive = cClient.Available;
          // ACHTUNG! PROBLEMSTELLE:
          // Eine Pause. Sonst kommt der Server mit der Bereitstellung nicht klar
          System.Threading.Thread.Sleep(100);
        } while (countReceive != cClient.Available);
        // Jetzt müssten alle Daten verfügbar sein
        // Darum kann jetzt abgeholt werden
        while (srClient.Peek() > -1)
        {
          if (ReturnResult != string.Empty)
            ReturnResult += Environment.NewLine;
          ReturnResult += srClient.ReadLine();
        }
        // interner Log-Eintrag
        LogEntry(ReturnResult);
        return ReturnResult;
      }
      catch (Exception ex)
      {
        throw new Exception("Befehl fehlgeschlagen. Server meldet: " +
                            ReturnResult +
                            Environment.NewLine +
                            ex.Message);
      }
    }

Die Problemstelle habe ich im Source kommentiert.
Die Lösung mit dem Sleep ist nur provisorisch. Bei einem DSL-Anschluss funtioniert es so meistens(!). Bei einer analogen Leitung eher selten.
Ohne Sleep funktioniert es meistens gar nicht, weil die Daten nicht schnell genug bereit stehen. Das Programm ist an der Stelle einfach zu schnell. :mrgreen:
Vermutlich muss ich irgendwie über den TimeOut gehen. Allerdings kann ich ja auch nicht bis zum TimeOut warten um dann zu merken, dass keine Daten mehr kommen.
Wer nimmt mir mal das Brett vom Kopf weg, damit das funktioniert?
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Fr 16.06.06 12:30 
Ich habe zwar noch nicht mit Sockets gearbeitet, aber dein Vorgehen kommt mir ein wenig spanisch vor.
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
        do
        {
          // Wieviel ist beim tcpClient verfügbar?
          countReceive = cClient.Available;
        } while (countReceive != cClient.Available);
Lassen wir das Sleep einfach weg, steht da: "Setze meine Variable auf einen bestimmten Wert. Wenn meine Variable nicht den bestimmten Wert hat, tue das gleiche nochmal.
Das erinnert ein wenig an
ausblenden C#-Quelltext
1:
2:
3:
4:
do
{
  int i = 42;
while (i != 42)
Daß diese eine Überprüfung einige hundert MAle schneller ist, als das Empfangen über den TCP-Client, egal welche Anbindung du hast, leuchtet schnell ein, denn das ist eine Operation die in Assembler wenige Takte benötigt (das Aufrufen der Methode schon eingerechnet).
Dein Warten auf neue verfügbare Daten ist bei diesem Vorgehen also zwingend notwendig.
Vielleicht möchtest du System.Net.Sockets.NetworkStream verwenden, der eine Eigenschaft NetworkStream.DataAvailable hat zu deren Verwendung es in der Referenzdoumentation ein Beispiel gibt:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
// Check to see if this NetworkStream is readable.
if(myNetworkStream.CanRead){
    byte[] myReadBuffer = new byte[1024];
    StringBuilder myCompleteMessage = new StringBuilder();
    int numberOfBytesRead = 0;

    // Incoming message may be larger than the buffer size.
    do{
         numberOfBytesRead = myNetworkStream.Read(myReadBuffer, 0, myReadBuffer.Length);

         myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));
                         
    }
    while(myNetworkStream.DataAvailable);

    // Print out the received message to the console.
    Console.WriteLine("You received the following message : " +
                                 myCompleteMessage);
}
else{
     Console.WriteLine("Sorry.  You cannot read from this NetworkStream.");
}
Sieht für mich deutlich eleganter aus, als deine Lösung.

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
jasocul Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6386
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Fr 16.06.06 12:40 
Die Schleife sieht nur im ersten Moment merkwürdig aus.
Die Eigenschaft Available ändert sich ständig (zumindest bei mir) bis die Gesamtgröße bekannt ist. Durch diese Schleife wollte ich sicher stellen, dass mit dem Lesen der Daten erst begonnen wird, wenn alles verfügbar ist.

Ich meine, dass ich die andere Variante auch schonmal getestet habe, aber bei der vielen Experimentiererei kann ich mich auch irren. Ich werde es auf jeden Fall nochmal prüfen.
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Fr 16.06.06 13:00 
user profile iconjasocul hat folgendes geschrieben:
Die Schleife sieht nur im ersten Moment merkwürdig aus.
Die Eigenschaft Available ändert sich ständig (zumindest bei mir) bis die Gesamtgröße bekannt ist.
Ja, das dachte ich mir schon, aber "ständig" ist relativ. Nach der Zuweisung dürfte der Test die nächste Operation sein, die ausgeführt wird. Innerhalb eines einzigen Taktes (in der Größenordnung einer Nanosekunde) ist es unwahrscheinlich, daß sich der Wert von Available ändert. Wie gesagt, die gesamte Schleife wird nicht länger sein als einige (wenige) Takte, sofern der Socketpuffer asynchron arbeitet (wovon ich ausgehe, weil alles andere unsinnig wäre), es ist einfach unwahrscheinlich, daß sich der Wert in dieser kurzen Zeit ändert, schließlich kommst du erst mit 1000Base-*-Ethernet in die Größenordnung von einer Nanosekunde pro Bit, nicht aber pro Frame. Mit DSL wirst du alle paar zigtausend Prozessortakte einen Frame empfangen, weshalb du deine Schleife irgendwie künstlich ausbremsen musst, oder auf eine andere Datenendeerkennungsmethode ausweichen musst. Da ich nicht so der Netzwerker bin (zumindest nicht auf Seite der Implementierung), kann ich dir aber leider nicht sagen, wie die klassische Herangehensweise an dieses Problem ist.

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
jasocul Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6386
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Fr 16.06.06 13:20 
Deswegen ist das auch nur eine provisorische Lösung gewesen, damit ich erstmal weiter programmieren kann. Für die Firmenleitung haben die 100ms gereicht, aber auch dann die Lösung ist einfach nicht akzeptabel. Deswegen habe ich das Topic ja erstellt. :wink: