TServerSocket und fehlende Bytes bei Übertragung



  • Hallo ...

    Ich habe ein Programm für einnen PocketPc (PPC) geschrieben und das schickt mittels WLan Messwerte zu meinem Desktop . Zum Empfangen meiner Daten benutze ich die TServerSocket Komponente (BCB6) und ich bekomme auch Werte. Das grosse Problem ist aber, dass ich in unregelmässigen Abständen, die falsche Anzahl an Bytes erhalte. Normalerweise verschicke ich 512 Byte, und das 3 Mal pro Sekunde für die WLan Verbindung. Tritt der Fehler auf werden weniger Bytes empfangen und gleichzeitig fehlen dadurch einige Messwerte.
    Das PPC Programm funzt ordentlich, habe es schon getestet. Es sendet die richtige Anzahl an Byte weg.
    Wo liegt da denn das Problem?

    void __fastcall TForm5::ServerSocket1ClientRead(TObjekt *Sender, TCustomWinSocket *Socket)
    {
       Byte buffer[512];
       int wert = Socket->ReceiveBuf(&buffer,512);
       Form1->Memo2->Lines->Add(wert);  // Ausgabe in einem Memofeld
    }
    

    PS: Habe auch schon versucht das ganze in grösseren Zeitabständen zu verschicken, aber das Problem war das selbe.....

    mfg
    devilempire



  • Ich denke nicht das das Senden ansich das Problem darstellt. Hast du ein Protokoll entwickelt, das dir Anfang und Ende der Messwerte kennzeichnet? Wenn nicht, dann lies dir mal folgenden FAQ-Beitrag durch: http://www.c-plusplus.net/forum/viewtopic.php?t=43719



  • Danke für Antwort deine Antwort, aber ich benutze bereits ein 11 Byte grosses Protokoll : 2x 0x7F als Synchronbytes und der Rest sind meine Daten. Durch die Synchronbytes weiss ich immer wo mein Datenpaket beginnt.
    Ich habe gestern aber noch herausgefunden, dass ich mit meinem PPC immer konstant 512 Byte als ein Paket rausschicke, aber auf der PC Seite diese Pakete zum Teil aneinander kleben. Also hab ich Pakete die grösser sind als 512 Byte. Ich habe auch noch errechnet, dass wenn man die falschen Pakete zusammenrechnet immer eine durch 512 teilbare Zahl entsteht.

    void __fastcall TForm5::ServerSocket1ClientRead(TObjekt *Sender, TCustomWinSocket *Socket)
    {
       Byte buffer[5000];
       int wert_length = Socket->ReceiveLength();
       int wert = Socket->ReceiveBuf(&buffer,wert_length);
       Form1->Memo2->Lines->Add(wert);  // Ausgabe in einem Memofeld
       Form1->Memo1->Lines->Add(wert_length);
    }
    

    Ich könnte mir vorstellen, dass es vielleicht Hardwareseitig irgendwo ein Problem gibt. Kann ich irgendwie anderst testen, was mein PC über sein WLan empfängt?



  • Scheint mir trotzdem ein Protokoll-Problem zu sein. Das Abschicken eines Paketes auf der Sendeseite heißt noch lange nicht, daß dieses Paket auch als Paket über das Netz übertragen wird. Und beim Lesen auf der Empfängerseite liest du die im symstemeigenen Empfangspuffer vorhanden Bytes aus. Und dort sind soviele Bytes, wie im Moment des Lesen gerade drin sind. Im übrigen mußt du sicherstellen, daß 0x7f nie als Nutzdatum vorkommt.

    Rob'



  • Was hat 0x7F mit dem Nutzdatum zu tun ?? Und welcher Wert wird nicht als Nutzdatum verwendet. Hast du eine Lösung wie ich eine fehlerfreie Kommunikation aufbaue. ? Vielleicht wäre es sinnvoll den systemeigenen Eingangspuffer immer zu leeren, wenn das gehen würde ? Vielleicht sollte ich es mal mit einem Stream ausprobieren, aber ich denke mal ein Stream nütz nur bei ungleichen Datenlängen, oder ? Ich hab jetzt auch mal probiert anstatt den BCB6, den M$ Visual $tudio .Net Compiler zu verwenden und ich habe das Gefühl das sich die Pakete nur noch seltener zusammenfügen, aber der Fehler ist der selbe.

    für jede Lösung wäre ich dankbar...

    mfg
    devilempire



  • Hi,

    mach das doch einfach so.

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
     AnsiString Buff = Edit1->Text;
     ServerSocket1->Socket->Connections[0]->SendText(Buff);
    }
    
    void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
          TCustomWinSocket *Socket)
    {
     AnsiString RecBuff = Socket->ReceiveText();;
     Memo1->Lines->Add(RecBuff);
    }
    

    Würde die Daten aber mit Zeichen in den String packen.

    z.B. so ...

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
     AnsiString Buff = "#" + Edit1->Text + "#" + Edit1->Text.Length() + "#";
     ServerSocket1->Socket->Connections[0]->SendText(Buff);
    }
    

    ... das dann mit ner for - Schleife auslesen ...

    void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
          TCustomWinSocket *Socket)
    {
     AnsiString Daten;
     AnsiString Test;
     int Count;
    
     if (RecBuff.SubString(1,strlen("#"))=="#")    
         {
          for (int a=2; RecBuff[a]!=RecBuff[1]; a++)
               {
                Daten = Daten + RecBuff[a];
                Count++;
              }
    
          for (int b=2+Count+1; RecBuff[b]!=RecBuff[1]; b++)
               {
                Test=Test+RecBuff[b];
               }
    
          if (Count == StrToInt(Text)) 
              {
               Memo1->Lines->Add(Daten);
              }
          else
              {
               //Befehl an Client zurück schicken das Daten neu gesendet
               //werden müssen
              } 
         }  
    }
    

    ... hoffe das hilft dir!

    Gruß Sebastian



  • @PlayazOnly

    Die Schleifen lassen sich mit AnsiString::Pos() und AnsiString::SubStr() viel einfacher lösen bzw. sie können dann einfach entfallen.



  • Hi,
    erstmal vielen Dank für die Antwort, werde ich gleich probieren...

    mfg


Anmelden zum Antworten