Entwickler-Ecke

Internet / Netzwerk - Datei Verschicken (SimpleTCP) Problem


DeltaEx - Mo 22.10.07 14:40
Titel: Datei Verschicken (SimpleTCP) Problem
Hallo zusammen,

Wenn ich eine Datei verschicke in dem Fall eine *.exe Datei, kommt bei mir auf der anderen Seite paar bytes weniger an.

Orignal: 619.008 Bytes
Kopie: 614.400 Bytes

Woran liegt das wohl?


Hier der Code vom Server ... der Server Sendet:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure TForm3.UpdateClient1Click(Sender: TObject);
var
 Stream: TMemoryStream;
 ID:Integer;
begin
 if UpdateOpenDialog.Execute then
 begin
    //Stream := TFileStream.Create(UpdateOpenDialog.FileName,fmOpenRead);
    Stream := TMemoryStream.Create;
    try
     ID:=ID_Update;
     Stream.WriteBuffer(ID,SizeOf(ID));
     Stream.LoadFromFile(UpdateOpenDialog.FileName);
     Form1.Server.SendStream(Connection, Stream);
    finally
     Stream.Free;
    end;
 end;
end;



Der Client der Empfängt:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TForm2.TCPClientInput(Sender: TObject; Stream: TStream;
var DisposeStream: Boolean);
var
  Str:String;
  ID:Integer;
  UpdateFileStream:TFileStream;
begin
    UpdateFileStream := TFileStream.Create(ExtractFilePath(ParamStr(0))+'update.exe',fmCreate);
    try
      UpdateFileStream.CopyFrom(Stream,Stream.Size);
    finally
     UpdateFileStream.Free;
    end;
end;



Woran kann es liegen?

Danke im voraus.

Moderiert von user profile iconNarses: --- Beiträge zusammengefasst ---

Ahhh wenn ich beim Client Stream.Size-4 hinzufüge:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TForm2.TCPClientInput(Sender: TObject; Stream: TStream;
var DisposeStream: Boolean);
var
  Str:String;
  ID:Integer;
  UpdateFileStream:TFileStream;
begin
    UpdateFileStream := TFileStream.Create(ExtractFilePath(ParamStr(0))+'update.exe',fmCreate);
    try
      UpdateFileStream.CopyFrom(Stream,Stream.Size-4);
    finally
     UpdateFileStream.Free;
    end;
end;


Dann bekomme ich mehr:

Original: 619.008 Bytes
Kopie: 619.004 Bytes

mmhh sehr komisch. Die exe ist aber immer noch kaputt :-(

Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt
Moderiert von user profile iconNarses: Topic aus Open Source Units verschoben am Mo 22.10.2007 um 14:43


DeltaEx - Mi 24.10.07 10:17

Keiner eine Idee?


DeltaEx - Mo 29.10.07 20:49

Hab immer noch keine Lösung ;-(


DeltaEx - Di 06.11.07 16:35

Wenn mir dabei keiner helfen kann, hat dann einer vielleicht eine alternative Lösung?


DeltaEx - Mi 07.11.07 23:14

Hallo Leute,

ich brächte echt dringend hilfe :-(

Wäre es eine hilfe wenn ich das komplette Programm mit Sourcecode hochladen würde?


Narses - Do 08.11.07 00:47

Moin!

user profile iconDeltaEx hat folgendes geschrieben:
ich brächte echt dringend hilfe :-(
Nimm halt einen IdFTPServer und einen IdFTPClient. :nixweiss:

cu
Narses


JayEff - Do 08.11.07 01:19

user profile iconDeltaEx hat folgendes geschrieben:
ich brächte echt dringend hilfe
So ungern ich es sage, aber hier im Delphi-Forum hat man mit Netzwerkfragen Pech. Keine meiner netzwerktechnischen Fragen ist je beantwortet worden... (zumindest nicht so, dass mein Programm danach liefe) Schätze, was diese Sachen betrifft gibt es zu viele Faktoren (Proxy, Router, bestimmte Einstellungen etc.), als dass man eine klare Antwort auf diese Fragen geben könnte.
Ich tippe darauf, dass dein Code völlig korrekt ist und der Fehler in irgendeiner Einstellung steckt, oder einer Hardwarekonfiguration...
Das mit dem FTP Server/Client ist natürlich ein guter Ansatz, vorallem, weil ich es selbst so versucht hab, natürlich erfolglos. Wenn du eine Lösung (mit FTP?) gefunden hast, poste sie doch bitte, damit ich's auch mitbekomme ;)

Viel Erfolg...


Narses - Do 08.11.07 01:25

Moin!

user profile iconJayEff hat folgendes geschrieben:
user profile iconDeltaEx hat folgendes geschrieben:
ich brächte echt dringend hilfe
So ungern ich es sage, aber hier im Delphi-Forum hat man mit Netzwerkfragen Pech. Keine meiner netzwerktechnischen Fragen ist je beantwortet worden... (zumindest nicht so, dass mein Programm danach liefe) Schätze, was diese Sachen betrifft gibt es zu viele Faktoren (Proxy, Router, bestimmte Einstellungen etc.), als dass man eine klare Antwort auf diese Fragen geben könnte.
Und das liegt dann am Delphi-Forum? :gruebel: Also, den Zusammenhang musst du mir nochmal erklären... :?

cu
Narses


alzaimar - Do 08.11.07 09:22

Ändere doch mal den Client

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm2.TCPClientInput(Sender: TObject; Stream: TStream;
var DisposeStream: Boolean);
var
  Str:String;
  ID:Integer;
  UpdateFileStream:TFileStream;
begin
    UpdateFileStream := TFileStream.Create(ExtractFilePath(ParamStr(0))+'update.exe',fmCreate);
    try
      Stream.Seek (SizeOf (Integer), soFromBeginning);                // <-- ID überspringen
      UpdateFileStream.CopyFrom(Stream,Stream.Size-SizeOf (Integer)); // <-- Datei lesen
    finally
     UpdateFileStream.Free;
    end;
end;

Wie hoch ist denn Stream.Size?

Alternative: FTP oder die den Indy TCP-Server und die WriteFile-Methode...


JayEff - Fr 09.11.07 00:45

user profile iconNarses hat folgendes geschrieben:
Und das liegt dann am Delphi-Forum? :gruebel: Also, den Zusammenhang musst du mir nochmal erklären...
Der Zusammenhang ist der, dass man im Delphi-Forum zu Netzwerkfragen wie auch in diesem Beispiel z.T. erst nach 4 Pushs auch nur eine Antwort bekommt. Netzwerkfragen sind unbeliebt, ob sich das auf's Delphi-Forum beschränkt weiß ich nicht und hab ich auch nie behauptet, aber ... OffTopic von einem Mod! :shock: ;)


DeltaEx - Mi 14.11.07 18:03

Danke für die Antworten.

@alzaimar
Leider habe ich mit dem Code das Gleiche Problem das mit 4 bytes fehlen.

Stream Größe:

Stream.Size-SizeOf (Integer) : 6961360
Stream.Size 6961364


Datei Größe Original: 6.961.364 Bytes
Datei Größe Kopie: 6.961.360 Bytes


alzaimar - Mi 14.11.07 19:20

Dann schick die Dateigröße mit. Dann muss das doch funktionieren.



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
procedure TForm3.UpdateClient1Click(Sender: TObject);
var
 Stream: TMemoryStream;
 Size, ID:Integer;
begin
 if UpdateOpenDialog.Execute then
 begin
    //Stream := TFileStream.Create(UpdateOpenDialog.FileName,fmOpenRead);
    Stream := TMemoryStream.Create;
    try
     ID:=ID_Update;
     Stream.WriteBuffer(ID,SizeOf(ID));
     Stream.LoadFromFile(UpdateOpenDialog.FileName);
     Size := Stream.Size;       // <<----
     Stream.WriteBuffer(Size,SizeOf(Size));  // <<----
     Form1.Server.SendStream(Connection, Stream);
    finally
     Stream.Free;
    end;
 end;
end;

Und der client


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure TForm2.TCPClientInput(Sender: TObject; Stream: TStream;
var DisposeStream: Boolean);
var
  Str:String;
  Size, ID:Integer;
  UpdateFileStream:TFileStream;
begin
    UpdateFileStream := TFileStream.Create(ExtractFilePath(ParamStr(0))+'update.exe',fmCreate);
    try
      Stream.Seek (SizeOf (Integer), soFromBeginning); 
      Strea.readBuffer (Size, SizeOf (Size))    // <-- Dateigröße lesen
      UpdateFileStream.CopyFrom(Stream,Size);     // <-- Datei lesen
    finally
     UpdateFileStream.Free;
    end;
end;


DeltaEx - Do 15.11.07 09:52

@alzaimar:

Vielen Dank das du dran bleibst.

Habe den Client und Server so angepasst wie du reingeschrieben hast.
Da habe ich ein Problem das der Client abstürzt.

Habe den Server Code so angepasst:



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
procedure TForm3.UpdateClient1Click(Sender: TObject);
var
 Stream: TMemoryStream;
 Size, ID:Integer;
begin
 if UpdateOpenDialog.Execute then
 begin
    //Stream := TFileStream.Create(UpdateOpenDialog.FileName,fmOpenRead);
    Stream := TMemoryStream.Create;
    try
   //  ID:=ID_Update;
   //  Stream.WriteBuffer(ID,SizeOf(ID));
     Stream.LoadFromFile(UpdateOpenDialog.FileName);

     Size := Stream.Size;
     Stream.WriteBuffer(Size, SizeOf(Size));
     Form1.Server.SendStream(Connection, Stream);
    finally
     Stream.Free;
    end;
 end;
end;



Also

Delphi-Quelltext
1:
2:
 //  ID:=ID_Update;
   //  Stream.WriteBuffer(ID,SizeOf(ID));


auskommentiert.

Jetzt kriege ich aber leider nur 3 Bytes geladen :-(


Im Debugger sieht es so aus:

Habe eine exe mit 527184 Bytes verschickt

Server:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
procedure TForm3.UpdateClient1Click(Sender: TObject);
var
 Stream: TMemoryStream;
 Size, ID:Integer;
begin
 if UpdateOpenDialog.Execute then
 begin
    //Stream := TFileStream.Create(UpdateOpenDialog.FileName,fmOpenRead);
    Stream := TMemoryStream.Create;
    try
   //  ID:=ID_Update;
   //  Stream.WriteBuffer(ID,SizeOf(ID));
     Stream.LoadFromFile(UpdateOpenDialog.FileName);

     Size := Stream.Size;                           // Stream.Size = 527184
     Stream.WriteBuffer(Size, SizeOf(Size));        // Size= 527184  SizeOf(Size) = 4
     Form1.Server.SendStream(Connection, Stream);
    finally
     Stream.Free;
    end;
 end;
end;





Client:



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TForm2.TCPClientInput(Sender: TObject; Stream: TStream;
var DisposeStream: Boolean);
var
  Str:String;
  Size, ID:Integer;
  UpdateFileStream:TFileStream;
begin
    UpdateFileStream := TFileStream.Create(ExtractFilePath(ParamStr(0))+'update.exe',fmCreate);
    try
      Stream.Seek (SizeOf (Integer), soFromBeginning);                // <-- ID überspringen
      Stream.ReadBuffer(Size, SizeOf(Size)); Stream.Size = 527184 //Size = 1244552 //SizeOf(Size) = 4
      UpdateFileStream.CopyFrom(Stream,Size); // <-- Datei lesen  //Stream.Size = 527184 Size= 3
      Memo1.Lines.Add('loda');
    finally
     UpdateFileStream.Free;
    end;
end;



Ankommen tuen wie gesagt nur 3 Bytes.
Kann es sein das SimpleTCP da Fehlerhaft ist?

Moderiert von user profile iconAXMD: Delphi-Tags hinzugefügt
Moderiert von user profile iconAXMD: Doppelposting entfernt.


alzaimar - Do 15.11.07 10:04

Sieht echt so aus, oder? Ich würde einfach auf Indy umsteigen. Dann ist das Thema nämlich erledigt.


DeltaEx - Do 15.11.07 10:30

Hallo alzaimar,

hast du irgendwo ein Beispiel wie ich mit Indy 10 eine Datei ... bzw. einen Stream verschicken kann? der für mein Fall passt, das der Server einem Client eine Datei schickt?


Danke


alzaimar - Do 15.11.07 10:58

Normalerweise läuft es so:

Client schickt an Server 'Gib mir mal die Datei'
Server schickt dann die Datei an den Client innerhalb der Verbindung.


Oder:
Der CLIENT schickt an den Server die Datei unaufgefordert.


Mit anderen Worten: Der Server reagiert auf Anfragen des Clients. Er bedient ('serves') also den Client, daher der Name.

Beispiele gibt es in den Demos zuhauf.

Du kannst z.B. im OnExecute-Ereignis des Servers eine Datei an den Client zurückschicken.

Beispiel: Client schickt nur einen Dateinamen zum Server und der Server schickt dann die Datei zurück:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
Procedure TfmMain.TCPServerExecute(AThread: TIdPeerThread);
Var
  sFilename: String;

Begin
  sFilename := AThread.Connection.ReadLn;
  AThread.Connection.WriteFile(sFilename);
End;


Aber versuchs einfach selbst. Die Handhabung ist wirklich denkbar einfach, das hab sogar ich kapiert.