Autor Beitrag
fsaction
Hält's aus hier
Beiträge: 2

WinXP
D7
BeitragVerfasst: Mi 14.04.04 17:34 
Hi,
ich möchte nacheinander Dateien über TCP versenden (von Server zu Client):
Die Probleme dabei sind: 1. Es werden alle Streams in eine Datei geschrieben und 2. Wenn ich nur eine Datei versende dann kommt sie nicht komplett beim Clienten an, es fehlen ein paar KB.

Kann mir jemand sagen wie ich das hinbekomme. Danke schon mal im Vorraus.

Hier die Ausschnitte der Sources:

Server:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
        for I:=0 to UPDATECOMPONENTCOUNT-1 do
          begin
            UPD_DB_QUERY.RecNo:=DOWNLOADDBID[I];
            AThread.Connection.WriteLn(UPD_DB_QUERY.FieldByName('filename').AsString);
            STREAM:=TFileStream.Create(DATADIRECTORY+PROGRAMNAME+'\'+UPD_DB_QUERY.FieldByName('filename').AsString, fmOpenRead);
            AThread.Connection.OpenWriteBuffer;
            AThread.Connection.WriteStream(STREAM);
            AThread.Connection.CloseWriteBuffer;
            STREAM.Free;
            AThread.Connection.WriteLn(UPD_DB_QUERY.FieldByName('component').AsString);
            AThread.Connection.WriteLn(UPD_DB_QUERY.FieldByName('version').AsString);
          end;


Client:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
  for I:=0 to UPDATECOMPONENTCOUNT-1 do
    begin
      FILENAME[I]:=TCPCLIENT.ReadLn;
      Stream:=TFileStream.Create(ExtractFilePath(ParamStr(0))+FILENAME[I]+'d', fmCreate);
      TCPCLIENT.OpenWriteBuffer;
      TCPCLIENT.ReadStream(STREAM);
      TCPCLIENT.CloseWriteBuffer;
      STREAM.Free;
      COMPONENTNAME[I]:=TCPCLIENT.ReadLn;
      COMPONENTVERSION[I]:=StrToInt(TCPCLIENT.ReadLn);
    end;
general_north
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Do 15.04.04 13:11 
Hallo,

es kann jederzeit passieren, dass ein TCP Paket gesplittet wird!

Beispiel:
Server App->Sendet 30KByte an SocketApi ;
SocketApi sendet nicht ein paket mit 30KByte sondern 2 Pakete mit jeweils 15KByte
Ein Router/Repeater zwischen den beiden Rechnern splittet die 15K pakete in jeweils 2 7,5K packete auf.
Empfänger bekommt erstes packet, notifiziert Client APP über lesevorgang. Client liest 7,5KByte;
Deine Applikation liest dieses packet und geht davon aus, dass das alles war.
3 weitere packete mit je 7,5kb treffen ein, und verbleiben ungehört in der SocketApi.


Was ich damit zum Ausdruck bringen möchte, ist die tatsache dass du
A) immer wissen solltest, wie gross die Gesamtinformation ist, die du erwartest
B) solange lesen musst, bis alle Bytes gelesen wurden.

Zu beachten: eine schleife Socket.Read bringt dir nichts, du musst vor dem lesen ein "Application.prozessMessages" aufrufen, damit die Notifizierung der socketApi deine Socketkomponente erreicht und diese dann die daten von der socketApi abrufen kann.


Klug ist es daher vorab 4 byte mit der grösse zu senden. Der Empfänger liest dann so lange bis er GENAU 4 byte gelesen hat! Nun weis der Empfänger wieviel Byte jetzt noch folgen müssen.

Der Witz an der Geschichte ist, das ein empfangenes Packet auch den Anfang eines weiteren Packetes beinhalten kann.

Nochmal Beispiel:
Sender sendet:
Paket1: 10,20,10,20,10
Paket2: 5,3,5,4

Empfänger bekommt:
Paket1: 10,20,10
Paket2: 20,10,5
Paket3: 3,5,4

Alles klar?

Ich weis leider nicht welche art socketkomponente du verwendest, aber scheinbar liegt dein Problem an dieser Stelle. Du musst eigene Methoden zum lesen/schreiben entwickeln, die dieses Prinziep beherzigen.


Mfg,

General North
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19321
Erhaltene Danke: 1748

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 15.04.04 13:23 
Titel: Bessere Lösung
Hi!

Also, eigene Methoden zu entwickeln, hieße hier, das Rad neu zu erfinden!

Sieh dir mal diese Komponeten an:
TSimpleTCPServer und TSimpleTCPClient

Diese machen eine Datenübertragung zwischen Server und Client bzw. umgekehrt und es können sogar mehrere Clients super-einfach mit dem Server verbunden und verwaltet werden.

Übersicht: (ganz unten auf der Seite)
www.utilmind.com/delphi3.html

Download:
www.utilmind.com/delphi/simpletcp.zip

Demo:
www.utilmind.com/del...mo/SimpleTCPDemo.exe


Diese Komponenten sind Freeware und ich benutze sie selbst. Kann ich nur empfehlen!

Viel Erfolg,
Sebastian
fsaction Threadstarter
Hält's aus hier
Beiträge: 2

WinXP
D7
BeitragVerfasst: Do 15.04.04 19:09 
Danke,

Nachdem ich die Übertragung der Dateigröße hinzugefügt habe hat alle super funktioniert.