AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi ServerSocket1ClientRead
Thema durchsuchen
Ansicht
Themen-Optionen

ServerSocket1ClientRead

Ein Thema von yildi · begonnen am 24. Sep 2006 · letzter Beitrag vom 26. Sep 2006
Antwort Antwort
Seite 1 von 2  1 2      
yildi

Registriert seit: 15. Sep 2006
23 Beiträge
 
#1

ServerSocket1ClientRead

  Alt 24. Sep 2006, 12:37
moin moin!

mein kleines serverprogramm kann mit dieser procedure binärdaten empfangen:

Delphi-Quellcode:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  SizeOfPacket: Integer;
  pBuffer: Pointer;
begin

      SizeOfPacket := Socket.ReceiveLength;
      GetMem(pBuffer, SizeOfPacket);
      Socket.ReceiveBuf(pBuffer^, SizeOfPacket);
      MUpdateStream.Write(pBuffer^, SizeOfPacket);
      FreeMem(pBuffer);

      if () then
        begin
          

          MUpdateStream.SaveToFile('update2.exe');
     Log.Lines.Add('('+TimeToStr(Now)+') System: Ein Server-Update wurde erfolgreich empfangen und wird nun installiert.');

          MUpdateStream.Free;
          MUpdateStream := TMemoryStream.Create;

        end;

end;


allerdings hab ich damit ein kleines problemchen. die ClientRead procedure wird ja quasi wie eine schleife immer wieder so lange aufgerufen, bis keine daten mehr empfangen werden. die empfangenen daten werden dann immer an meim MUpdateStream angehängt. am ende möchte ich dann aus dem stream eine datei erstellen.

Nur ich weiss leider nicht, wie ich meine bedingung formulieren muss, dass dieser teil quasi nur nach dem letzten empfangenen paket aufgerufen wird. man könnte von seiten des clients vorher die dateigröße übermitteln, nur dafür müsste ich insgesamt mein programm zu sehr umbauen. hat jemand noch eine andere idee ?

danke!
yildi
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

Re: ServerSocket1ClientRead

  Alt 24. Sep 2006, 12:43
Die Datengröße ist leider erforderlich ... Du könntest vor dem Senden der Binärdaten mit SendText einfach z.B. "Data:27526" (länge in Byte) an den Server senden.

Florian
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#3

Re: ServerSocket1ClientRead

  Alt 24. Sep 2006, 13:03
Da dies schon eine Art Protokoll darstellt (was du hier brauchst) würde ich trotzdem diesen Weg nicht im Detail empfehlen. Er überträgt Binärdaten, warum sollte er also eine Mischung aus Text und Binärdaten machen? Vor allem: Wie weiss er, dass es noch eine Ziffer der Byteangabe ist oder schon das erste Zeichen des Binärstreams?

Empfehlung: Sende vor den Binärdaten einen INT64 direkt über den Stream, welche die Länge der nachfolgenden Binärdaten angibt. Dann hast du auf der Empfangsseite eine einfache Möglichkeit den kompletten Empfang zu ermitteln (Stream.Size und vorher gesendete Zahl). Und beachte, dass der letzte empfangene Block grösser sein kann, als der Vollendung des Streams nötige.
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#4

Re: ServerSocket1ClientRead

  Alt 24. Sep 2006, 13:23
Er kann prüfen, ob die ersten Zeichen DATA sind, dann weiß er, dass es sich um die Längenangabe handelt.

Ansonsten kannst du dir mal meinen OpenSource Chat angucken:
http://www.delphipraxis.net/internal...highlight=chat

Florian
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
yildi

Registriert seit: 15. Sep 2006
23 Beiträge
 
#5

Re: ServerSocket1ClientRead

  Alt 24. Sep 2006, 14:28
hmm danke für eure hilfe..

nur wie erkenn ich denn, wann die größenangabe nach DATA: zu ende ist ?
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#6

Re: ServerSocket1ClientRead

  Alt 24. Sep 2006, 18:45
Zitat von yildi:
nur wie erkenn ich denn, wann die größenangabe nach DATA: zu ende ist ?
Diese Frage bleibt offen und genauso ist die Sache mit abprüfen ob vorne "DATA" steht, genauso schwachsinnig. Damit würdest du jede Binärdatei vor der Übertragung ausschliessen, welche mit "DATA" anfängt oder dieses Wort enthält. Schick mal den Text dieses Threads über den Socket und du wirst ein Problem bekommen.

@yildi:
Schick vor dem Stream einfach dessen Grösse mit:
Delphi-Quellcode:
Var
  lSize: Int64;
Begin
  lSize := Stream.Size; // Grösse der zu sendenen Datei
  Socket.SendBuf(lSize, SizeOf(lSize)); // Grösse vorneweg schicken
  Socket.SendStream(Stream);
End;
Beim Empfänger:
Delphi-Quellcode:
  fSize : Int64; // als Klassenmitglied deklarieren
  fReceiveStream: TStream; // dito
...

Procedure SocketEmpfangen(...)
Var
  lBuff: Pointer;
  lSize: Int64;
Begin
  If Not Assigned(fReceiveStream) And ( Socket.ReceiveLength >= SizeOf(Int64) ) Then
  Begin
    Socket.ReceiveBuf(fSize, SizeOf(fSize));
    fReceiveStream := {TMemoryStream}TFileStream.Create(...);
  End
  Else If Assigned(fReceiveStream) Then
  Begin
    lSize := Min(fSize - fReceiveStream.Size, Socket.ReceiveLength);
    lBuff := GetMem(lSize);
    Try
      Socket.ReceiveBuf(lBuff^, lSize);
      fReceiveStream.WriteBuffer(lBuff^, lSize);
    Finally
      FreeMem(lBuff);
    End;

    If ( fReceiveStream.Size = fSize ) Then
    Begin
      FreeAndNil(fReceiveStream);
      fSize := 0;
    End;
  End;
End;
ein kleiner Pseudocode um dies zu verdeutlichen...
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#7

Re: ServerSocket1ClientRead

  Alt 24. Sep 2006, 19:04
Zitat von Muetze1:
Diese Frage bleibt offen und genauso ist die Sache mit abprüfen ob vorne "DATA" steht, genauso schwachsinnig. Damit würdest du jede Binärdatei vor der Übertragung ausschliessen, welche mit "DATA" anfängt oder dieses Wort enthält. Schick mal den Text dieses Threads über den Socket und du wirst ein Problem bekommen.
Meinen Beispielchat mal angeguckt?
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#8

Re: ServerSocket1ClientRead

  Alt 24. Sep 2006, 20:26
Zitat von Florian Bernd:
Meinen Beispielchat mal angeguckt?
Ok, habe ich nun gemacht.
  • Warum nutzt du einen TMemoryStream beim versenden der Daten? Schick damit mal eine 4 GB Datei und schon kratzt er erstmal stundenlang seine Swap Datei voll. Und warum kein SendStream() der TCustomWinSockets nutzen? Dieser kehrt sofort zurück und wartet nicht, bis alles im Socket Buffer ist...
  • Warum definierst du eigene Typen für Objektmethoden die schon definiert sind? z.B. hättest du dir einfach TOnRead = TNotifyEvent; definieren können.
  • Was sollen die Sleep()'s zwischen den Teilstrings? Dein Protokoll teilt die Teilstrings und nicht eine Pause zwischen dem absenden. Benutz dein Chat mal über ein wackliges Netzwerk und du wirst dich freuen, weil diese Teilung völlig nichtig ist.
  • Mit dem "StLG:" und der angehängten ASCII Zahl gehst du auch fest davon aus, dass du eine Teilung bekommst, wenn du die Strings mit einem Sleep() trennst beim senden. Dem ist nicht so - dafür gibt es überhaupt keine Handhabe. Da dies in deinem LAN funktioniert sagt nichts aus.
  • Dein Splitten des Strings beachtet keine Verschiebung, falls z.B. das Sleep() mal nicht gewirkt hat oder noch ein Zeichen vom letzten Kommando im Stream war.
  • OnFileReadF(): Du schaust nirgendwo, wieviel überhaupt empfangen wurde. Was ist, wenn du vom Socket aufgerufen wird aber dieser gerade mal "Date" empfangen hat? Dein Vergleich geht schief und er schaltet nie in den Datenmodus, da er dieses niemals erreicht.
  • OnFileReadF(): du beachtest überhaupt nicht wieviel eigentlich noch zur Datei gehört. Du vergleichst auf grösser gleich und schreibst alles was im Socket Buffer ist direkt in die Datei. Somit wird die Datei mit deinem Chat sogar grösser nach der Übertragung.

Das wolltest du bestimmt nicht hören, aber es sind viele Faktoren die gegen eine sichere Funktionsweise des Chats sprechen.
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#9

Re: ServerSocket1ClientRead

  Alt 24. Sep 2006, 21:13
Nagut, du hast mich überzeugt Wobei ich zu meiner Verteidigung erwähnen muss, dass dies eine meiner ersten Spielereien mit den Sockets war ...

Florian
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#10

Re: ServerSocket1ClientRead

  Alt 24. Sep 2006, 21:56
Zitat von Florian Bernd:
Nagut, du hast mich überzeugt Wobei ich zu meiner Verteidigung erwähnen muss, dass dies eine meiner ersten Spielereien mit den Sockets war ...
Man kann auch nicht alles sofort wissen und können. Ich hatte mich mal zwangsweise mit den Sockets ein wenig auseinander setzen müssen. Man lernt eh mit der Zeit und den Projekten...
  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 04:48 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