Protokollentwicklung



  • junix schrieb:

    Scroll mal im CPU-Fenster hoch bis zur nächsten dir bekannten Zeile in C.

    Wie meinst du das? Bei mir stehen im CPU-Fenster nur Assembler befehle.
    Habe jetzt mal das mit dem Aufruf-Stack gemacht, da steht bei mir: ntdll.dll 😕



  • Es kann doch sein, dass die VCL intern mit WSAAsyncSelect() arbeitet. Dann wird beim Eintreffen von Daten eine Message an die Form gesendet. D.h., er geht wieder in OnReceive rein. Eine feine Rekursion, die möglicherweise den Fehler verursacht...
    So kannst du einfach prüfen, ob meine Vermutung tatsächlich der Fall ist:

    void __fastcall TForm1::OnReceiveData(TObject* Sender)  // Oder was weiß ich, wie die Rotine bei dir heißt...
    {
       static bool IsProcessMessagesOn = false;
    
       if( !IsProcessMessagesOn )
       {
          BytesReceive = Socket->ReceiveBuf(Buffer, BufferSize); //Buffer auslesen 
          Stream->Write(Buffer, BytesReceive);                      //Buffer in Stream schreiben 
          TotalBytesReceived += BytesReceive;                       //Anzahl empfangene Bytes aufsummieren 
          Progress->TransferStatus->Progress = TotalBytesReceived; 
          Progress->SendBytesLabel->Caption = TotalBytesReceived; 
    
          IsProcessMessagesOn = true;
          Application->ProcessMessages(); 
          IsProcessMessagesOn = false;
    
          if(TotalBytesReceived == TotalBytes) 
          { 
             free(Buffer);                                   //Speicherbereich wieder frei geben 
             Progress->Close();                              //Statusfenster schliessen 
             Stream->Seek(0, soFromBeginning);               //Stream auf Anfang setzten 
             Stream->SaveToFile(SaveDialog1->FileName);      //Stream abspeichern 
             Stream -> Clear();                              //Speicher freigeben 
             delete Stream;                                  //Stream frei geben 
             delete [] Buffer;                               //Buffer frei geben 
             FileReadyToReceive = false; 
             FileSizeReadyToReceive = false; 
             FileSizeReceive = false; 
             ServerSocket1->Close(); 
          }
       }
    }
    

    So könnte es zwar sein, dass nicht alles durchkommt, aber du wirst merken, ob du wieder eine AccessViolation bekommst oder nicht. Ich würde dir eh dazu raten, die ganze daten-Empfangs-Routine in einen eigenen Thread zu packen.



  • Super Tip danke, genau da lag der Fehler.👍 Dann werde ich einfach die Anzeige der empfangenen Bytes weglassen, das TCGauge genügt ja auch.



  • Bei mir funzt es mittlerweile auch schon gut, Perfekt ist es aber noch nicht da Teilweiße die Sendeschleife rausspringt obwohl der File noch gar nicht zu ende gesendet wurde:

    char buf[1024];
     int c,b;
    
     TFileStream *in = new TFileStream(Form1->OpenDialog1->FileName, fmOpenRead);
     in->Seek(0,soFromBeginning);
    
    do
         {
             Application->ProcessMessages();
             b = in->Read(buf,sizeof(buf));
             c = Form1->ClientSocket1->Socket->SendBuf(buf,b);
    
            while(c == -1)
            {
             Application->ProcessMessages();
             b = in->Read(buf,sizeof(buf));
             c = Form1->ClientSocket1->Socket->SendBuf(buf,b);
            }
        }
         while(b == sizeof(buf));
         delete in;
    

    Was mache ich falsch da er manchmal zu früh aufhört zu senden? Beispiel: Von 123456 bytes sendet er dann meistens nur 123453. Wie schaffe ich es das er immer die komplette Datei überträgt ?



  • So, nun hab ich ne einigermaßen stabile Variante ausgetüftelt:

    char buf[1024];
     int c,b,bytecount = 0;
    
         TFileStream *in = new TFileStream(Form1->OpenDialog1->FileName, fmOpenRead);
         in->Seek(0,soFromBeginning);
    
          do
         {
             Application->ProcessMessages();
             b = in->Read(buf,sizeof(buf));
             c = Form1->ClientSocket1->Socket->SendBuf(buf,b);
    
               if (c != -1)
               {
                UploadWindow->ProgressBar1->Position += c;
                bytecount += c;
                UploadWindow->Label7->Caption = String(UploadWindow->ProgressBar1->Position)+ " bytes";
               }
            while(c == -1)
            {
             c = Form1->ClientSocket1->Socket->SendBuf(buf,b);
    
                   if (c != -1)
                 {
                  UploadWindow->ProgressBar1->Position += c;
                  bytecount += c;
                  UploadWindow->Label7->Caption = String(bytecount)+ " bytes";
                 }
            }
        }
         while(File_Size > bytecount && b == sizeof(buf));
         delete in;
    

    Sieht jemand von euch Fehler 😕 mehrere Files sendet er problemlos aber bei einigen Bricht er ziemlich am Ende des Files die do-while Schleife ab



  • Hab den Fehler gefunden ! Jetzt läufts wie geschmiert



  • @Zero01 währe nett wenn du den fehlerfreien Code auch Posten könntest!

    Bin nämlich auch gerade Dabei so einen File Transfer zu schreiben.

    danke

    gruß



  • UNd was genau bereitet dir Probleme?

    Oder war "schreiben" nur ein Tippfehler und du wolltest "kopieren" schreiben? (-;



  • void SendFile(String file_path,String ip_address,int File_Size)
    {
     char buf[1024];
     int c,b,bytecount = 0;
    
     int limiter = file_path.LastDelimiter("\\");
     int stringlenght = file_path.Length() - limiter;
     String Filename = file_path.SubString(limiter + 1,stringlenght);
    
     UploadWindow = new TForm3(Form1);
     if(UploadWindow)
       {
          UploadWindow->ClientSocket1->Address = ip_address;
          UploadWindow->ClientSocket1->Open();
          UploadWindow->Caption = "File Transfer ";
          UploadWindow->Label4->Caption = "Uploading...";
          UploadWindow->Label6->Caption = IntToStr(File_Size);
          UploadWindow->Label8->Caption = file_path;
          UploadWindow->ProgressBar1->Position = 0;
          UploadWindow->ProgressBar1->Min = 0;
    
          if (File_Size > 0)
          UploadWindow->ProgressBar1->Max = File_Size;
    
          UploadWindow->Label3->Caption = Filename;
          UploadWindow->Show();
          UploadWindow->in->Seek(0,soFromBeginning); //-- in ist der FileStream
          do
         {
             Application->ProcessMessages();
             b = UploadWindow->in->Read(buf,sizeof(buf));
    
             if(UploadWindow->ClientSocket1->Socket->Connected)
             c = UploadWindow->ClientSocket1->Socket->SendBuf(buf,b);
    
               if (c != -1)
               {
                UploadWindow->ProgressBar1->Position += c;
                bytecount += c;
                UploadWindow->Label7->Caption = String(UploadWindow->ProgressBar1->Position)+ " bytes";
               }
            while(c == -1 && UploadWindow->ClientSocket1->Socket->Connected)
            {
             Application->ProcessMessages();
    
             if(UploadWindow->ClientSocket1->Socket->Connected)
             c = UploadWindow->ClientSocket1->Socket->SendBuf(buf,b);
    
                   if (c != -1)
                 {
                  UploadWindow->ProgressBar1->Position += c;
                  bytecount += c;
                  UploadWindow->Label7->Caption = String(bytecount)+ " bytes";
                 }
            }
        }
         while(b == sizeof(buf) && UploadWindow->ClientSocket1->Socket->Connected);
    
         if (IntToStr(bytecount) == IntToStr(File_Size))
         UploadWindow->Close();
         else
         {
          if(UploadWindow->Label4->Caption != "Socket Error !")
          UploadWindow->Label4->Caption = "Stream corrupt, size dismatch";
         }
    
      }
     }
    

    Versuchs mal bei dir. Wäre nett wenn wir über die Fehler diskutieren könnten 👍



  • Trenn am besten den GUI Code vom Netzwerk-Code. Sieht ja total gefrickelt aus.


Anmelden zum Antworten