AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Warum kann ich keine Form im Execute-Rutine des TCP Createn
Thema durchsuchen
Ansicht
Themen-Optionen

Warum kann ich keine Form im Execute-Rutine des TCP Createn

Offene Frage von "jonny"
Ein Thema von jonny · begonnen am 15. Jan 2004 · letzter Beitrag vom 29. Jan 2004
Antwort Antwort
Seite 1 von 2  1 2      
jonny

Registriert seit: 15. Dez 2003
235 Beiträge
 
Delphi 7 Enterprise
 
#1

Warum kann ich keine Form im Execute-Rutine des TCP Createn

  Alt 15. Jan 2004, 13:37
Hallo ich habe ein ProblemIch Will schreibe gerade ein Programm mit dem man Dateien über das Internet schicken kann doch sollen die dateien nicht sofort losgeschickt werden sondern der Benutzer soll bestätigen können ob er die Datei annehmen oder verweigern will.

Also ich schicke über Die Indy TCP einige Daten wie die IP , den UserNamen, Eine identifikationsNummer, die Dateinamen und die Gesammtgrösse der Dateien.

Der TCP Server bekommt die Sachen und soll dann eine Form erstellen in die er dann alles einträgt und wo der Benutzer dann bestätigen kann.

So hier der Quellcode der Procedure die der TCP Server Aufruft wenn er Eine Anfrage bekommt.
Code:
procedure TfrmMain.GetFileFrom(User, IP, DMIN, Description, FileSize: String; Files: TStringList);
var TfGF: TfrmGetFile;
begin
  If Application.FindComponent('GF' + DMIN) = Nil Then
  begin
    Application.CreateForm(TfrmGetFile, TfGF);
    TfGF.Name:='GF' + DMIN;
    TfGF.lblUserName.Caption := User;
    TfGF.TCP.Host := IP;
    TfGF.SetStatus('Online');
    TfGF.lstboxFiles.Items.Assign(Files);
    TfGF.memDescription.Text:=Description;
    TfGF.lblFileSize.Caption:=FileSize;
  end
  else
  begin
    TfGF:=(Application.FindComponent('GF' + DMIN) As TfrmGetFile);
    TfGF.TCP.Host := IP;
    TfGF.SetStatus('Online');
    TfGF.lstboxFiles.Items.Assign(Files);
    TfGF.memDescription.Text:=Description;
    TfGF.lblFileSize.Caption:=FileSize;
    TfGF.SetFocus;
  end;
end;
Rufe ich die Procedure mit einen Button auf funktionirt die wird die Procedure im Execute-Ereigniss des TCP Servers aufgerufen bekomme ich die Meldung "Leinwand/Bild erlaubt kein zeichnen".

Was kann das Sein? Wie kann ich es machen das es funktioniert?
  Mit Zitat antworten Zitat
jonny

Registriert seit: 15. Dez 2003
235 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: Warum kann ich keine Form im Execute-Rutine des TCP Crea

  Alt 19. Jan 2004, 11:47
Hat denn keiner ne Idee?
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#3

Re: Warum kann ich keine Form im Execute-Rutine des TCP Crea

  Alt 25. Jan 2004, 16:40
Diese "wunderschöne Meldung" kenne ich auch ganz gut *g

Die tritt immer auf, wenn Dein OnExecute Code des Server's nicht Threads sicher ist.

Also :

Alles was VCL betrifft und nicht thread sicher ist mit syncronize aufrufen !

Ich habe gesehen das Du eine Form erzeugst, diese solltest Du nicht Modal machen.

Ich hoffe das hat Dir schon mal geholfen, oder brauchst Du noch mehr Details ?

Gruß Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
jonny

Registriert seit: 15. Dez 2003
235 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: Warum kann ich keine Form im Execute-Rutine des TCP Crea

  Alt 26. Jan 2004, 12:29
Also ich öffne die nicht modal.
Was ist denn zum Beispiel nicht Thread Sicher?

Ein paar Details währen schon hilfreich.
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#5

Re: Warum kann ich keine Form im Execute-Rutine des TCP Crea

  Alt 26. Jan 2004, 12:44
Hi,

poste bitte mal Dein OnExecute des Servers !!

Den von dort wirst Du doch GetFileFrom(User, IP, DMIN, Description, FileSize: String; Files: TStringList); aufrufen, oder ?

Und da dieser Aufruf mit Parametern geschiet gehe ich davon aus das Du den Aufrug nicht syncronisierst.

Gruß Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
jonny

Registriert seit: 15. Dez 2003
235 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: Warum kann ich keine Form im Execute-Rutine des TCP Crea

  Alt 26. Jan 2004, 13:35
So hier ist die OnExecute:

Code:
procedure TfrmMain.TCPServerExecute(AThread: TIdPeerThread);
var
  SessionID: Integer;

  procedure DoLog(const Msg: String);
  var
    S: String;
    I: Integer;
  begin
    S := Format('%s-%0.6d: %s', [FormatDateTime('YYMMDD HHNNSS ZZZ', Now), SessionID, Msg]);
    for I := 1 to Length(S) do
      if S[I] in [#10,#13] then S[I] := ' ';
  // da Memo1.Lines.Add() intern über SendMessage() arbeitet sollte dies Threadsafe sein.
//    Memo1.Lines.Add(S);
  end;

  function ReadByte: Byte;
  begin
    AThread.Connection.ReadBuffer(Result, SizeOf(Result));
  end;

  function ReadLong: Cardinal;

    function SwapLong(Value: Cardinal): Cardinal;
    // konvertiert Big Endian zu Little Endian
    // im INet ist es üblich ALLE Daten in Big Endian zu übertragen
    asm
      BSWAP EAX
    end;

  begin
    AThread.Connection.ReadBuffer(Result, SizeOf(Result));
    Result := SwapLong(Result);
  end;

  function ReadString: String;
  begin
    SetLength(Result, ReadByte);
    AThread.Connection.ReadBuffer(Result[1], Length(Result));
  end;

  procedure WriteByte(Value: Byte);
  begin
    AThread.Connection.WriteBuffer(Value, SizeOf(Value));
  end;

  procedure WriteString(const Value: ShortString);
  begin
    WriteByte(Length(Value));
    AThread.Connection.WriteBuffer(Value[1], Length(Value));
  end;

var
  FileName: String;
  FileSize, MSGSize: Cardinal;
  FileStream: TStream;
  MSGStream: TStream;
  I, Accept: Integer;
  User, DMIN, IP: String;
  Files: TStringList;
  Description, SizeOfFiles: String;
  GetMSG, GetFileRequest, GetAnswerOfFileRequest, GetURL: Boolean;
begin
  SessionID := LastSessionID;
  Inc(LastSessionID);

  GetMSG:=False;
  GetFileRequest:=False;
  GetAnswerOfFileRequest:=False;
  GetURL:=False;
  Accept:=0;

  try
    DoLog(Format('Client connect at IP ', [AThread.Connection.Socket.Binding.PeerIP]));
    if (ReadByte = 1) and (ReadString = 'MyUpload 1.0') then // LOGIN
    begin
// Client hat sich korrekt identifiziert sende Bestätigung und warte auf Kommandos
      WriteByte(1);
      while True do
        case ReadByte of
          0: begin // NULL
               WriteByte(0);
             end;
          2: begin // LOGOUT
               DoLog('Client logout');
               Break;
             end;
          3: begin // ERROR
               DoLog(Format('Client error %d, %s', [ReadByte, ReadString]));
               Break;     // Fehler fürht IMMER zum Abbau der Verbindung
             end;
          4: begin // UPLOAD
               DMIN:=ReadString;
               User:=ReadString;
               IP:=ReadString;

               FileName := ExtractFilePath(ParamStr(0)) + 'Upload\' + ReadString;
               FileSize := ReadLong;
               DoLog(Format('Client upload %5d, %s', [FileSize, FileName]));
               try
                 FileStream := TFileStream.Create(FileName, fmCreate);
                 try
                   AThread.Connection.ReadStream(FileStream, FileSize);
                 finally
                   FileStream.Free;
                 end;
                 WriteByte(4);
               except
                 on E: Exception do
                 begin
                   WriteByte(3); // ERROR
                   WriteByte(1);
                   WriteString(E.Message);
                   Break;
                 end;
               end;
             end;
          5: begin // MESSAGE
               DMIN:=ReadString;
               User:=ReadString;
               IP:=ReadString;

               MSGSize := ReadLong;
               try
                 MSGStream := TMemoryStream.Create;
                 try
                   AThread.Connection.ReadStream(MSGStream, MSGSize);
                 finally
                   GetMSG:=True;
                 end;
                 WriteByte(5);
               except
                 on E: Exception do
                 begin
                   WriteByte(3); // ERROR
                   WriteByte(1);
                   WriteString(E.Message);
                   Break;
                 end;
               end;
             end;
          6: begin // URL
               DMIN:=ReadString;
               User:=ReadString;
               IP:=ReadString;

               ReadString;
               ReadString;
               
               GetURL:=True;
               WriteByte(6);
             end;
          7: begin // ASK FOR UPLOAD
               DMIN:=ReadString;
               User:=ReadString;
               IP:=ReadString;

               try
                 Files:=TStringList.Create;
                 Files.Clear;
                 try
                   For I:=0 To ReadLong - 1 Do
                   begin
                     Files.Add(ReadString);
                   end;
                   Description:=ReadString;
                   SizeOfFiles:=ReadString;
                 finally
                   GetFileRequest:=True;
                 end;
                 WriteByte(7);
               except
                 on E: Exception do
                 begin
                   WriteByte(3); // ERROR
                   WriteByte(1);
                   WriteString(E.Message);
                   Break;
                 end;
               end;
             end;
          8: begin // ACCEPT OR DISACCEPT THE UPLOAD
               DMIN:=ReadString;
               User:=ReadString;
               IP:=ReadString;

               Accept:=ReadByte;

               WriteByte(8);

               GetAnswerOfFileRequest:=True;
             end;
          9: begin // STATUSCHECK
               DMIN:=ReadString;
               User:=ReadString;
               IP:=ReadString;

               WriteString(sStatus);

               WriteByte(9);
             end;
        else
          begin // Invalid Code;
            DoLog('Client sends unknown command, terminate');
            WriteByte(3);
            WriteByte(0); // Errorcode
            WriteString('unknown kommand');
            Sleep(1);
            Break;
          end;
        end;
    end; // falsches/fehlendens Client-Login, trenne einfach die Verbindung, Server ist im Stealth mode
  finally
    DoLog('Client terminated');
    try
      Sleep(1);
      AThread.Connection.Disconnect;
    except
    end;
  end;

  If GetMSG Then
  begin
    ShowMessage(User, DMIN, IP, MSGStream);
    MSGStream.Free;
  end
  else If GetFileRequest Then
  begin
    GetFileFrom(User, IP, DMIN, Description, SizeOfFiles, Files);
    Files.Free;
  end
  else If GetAnswerOfFileRequest Then
  begin
    AcceptSendFile(User, DMIN, IP, Accept);
  end
  else If GetURL Then
  begin
    //
  end;

end;
  Mit Zitat antworten Zitat
jonny

Registriert seit: 15. Dez 2003
235 Beiträge
 
Delphi 7 Enterprise
 
#7

Re: Warum kann ich keine Form im Execute-Rutine des TCP Crea

  Alt 27. Jan 2004, 18:53
Hey DataCool hast du mich etwa vegessen?
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#8

Re: Warum kann ich keine Form im Execute-Rutine des TCP Crea

  Alt 28. Jan 2004, 10:15
@Jonny:

Ja hab ich ! Viel Stress hier in der Firma, da bekommt man einen Tunnelblick

Dein Problem ist etwas schwierig zu erklären, es liegt auf jeden Fall am Multi-Threading !!!

D.H. das jeder Befehlsaufruf der mit der VCL zu tun hat, syncronisiert aufgerufen werden muss !!

Bsp.:

Code:
procedure updateMyForm;
begin
  form1.caption := 'Ich wurde syncronisiert ;-)';
end;

// Im OnExecute des Servers folgendes
begin
  // ... Dein Code
  ATHread.syncronize(updatemyForm);
  // ... Nochmehr Code :wink:
end;
Wie Du sicherlich festgestellt hast, hat die Procedure updateMyForm keine Parameter und diese benötigst Du ja, deshalb kommt gleich noch ein zweites posting, mit der Lösung !
Oder Du meldest Dich bei mir : TelWell-Nr.: 1011 oder icq : 23764631


Gruß Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#9

Re: Warum kann ich keine Form im Execute-Rutine des TCP Crea

  Alt 28. Jan 2004, 11:06
Hi John,

hier ist jetzt die Lösung, sorry nochmal für's warten.

Ich habe jetzt eine Klasse zur Syncronisation erstellt, das ist meiner Meinung nach der einfachste Weg.
Bei Fragen einfach melden

Code:
type

   TSyncGetFileFrom = Class
      private
         fUser,
         fIP,
         fDMIN,
         fDescription,
         fFileSize: String;
         fFiles: TStringList;
      protected
       {}
      public
         Constructor Create; override;
         Destructor Destroy; override;

         property User : String read fUser write fUser;
         property IP  : String read fIP  write fIP;
         property DMin : String read fDMin write fDMin;
         property Description : String read fDescription write fDescription;
         property FileSize : String read fFileSize write fFileSize;
         property Files : TStringList read fFiles write fFiles;

         // call showForm with syncronize from a Thread
         procedure showForm;
   end;


implementation

// uses Unit wo TfrmGetFile definiert ist

{ TSyncGetFileFrom }

constructor TSyncGetFileFrom.Create;
begin
   inherited;
   fFiles := TSTringList.Create;
end;

destructor TSyncGetFileFrom.Destroy;
begin
   FreeAndNil(fFiles);
   inherited;
end;

// look is extactly your code, but knoe syncronized
procedure TSyncGetFileFrom.showForm;
begin
   If Application.FindComponent('GF' + DMIN) = Nil Then
   begin
      Application.CreateForm(TfrmGetFile, TfGF);
      TfGF.Name:='GF' + DMIN;
      TfGF.lblUserName.Caption := User;
      TfGF.TCP.Host := IP;
      TfGF.SetStatus('Online');
      TfGF.lstboxFiles.Items.Assign(Files);
      TfGF.memDescription.Text:=Description;
      TfGF.lblFileSize.Caption:=FileSize;
   end
   else
   begin
      TfGF:=(Application.FindComponent('GF' + DMIN) As TfrmGetFile);
      TfGF.TCP.Host := IP;
      TfGF.SetStatus('Online');
      TfGF.lstboxFiles.Items.Assign(Files);
      TfGF.memDescription.Text:=Description;
      TfGF.lblFileSize.Caption:=FileSize;
      TfGF.SetFocus;
   end;
end;

// So und im OnExecute des Server rufst Du jetzt folgendes auf :

Var mySyncForm : TSyncGetFileForm;
begin
  // ... Code
  mySyncForm := TSyncGetFileForm.Create;
  mySyncForm.User := User;
  mySyncForm.IP := IP;
  mySyncForm.DMin := DMin;
  mySyncForm.DEscription := Description;
  mySyncForm.FileSize := SizeOfFiles;
  mySyncForm.Files.assign(Files);
  // use syncronize now
  aThread.syncronize(mySyncForm.showForm);
  // That's it
end;
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
jonny

Registriert seit: 15. Dez 2003
235 Beiträge
 
Delphi 7 Enterprise
 
#10

Re: Warum kann ich keine Form im Execute-Rutine des TCP Crea

  Alt 28. Jan 2004, 16:07
Das sieht ja kompeziert aus!

!!!!!!!!!!!!!Danke!!!!!!!!!!!!!!!!!

werde es gleich mal ausprobieren.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:36 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz