AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Dateiaustausch zwischen clientsocket und serversocket..^^
Thema durchsuchen
Ansicht
Themen-Optionen

Dateiaustausch zwischen clientsocket und serversocket..^^

Ein Thema von cRayZo · begonnen am 6. Okt 2007 · letzter Beitrag vom 12. Okt 2007
Antwort Antwort
Seite 3 von 5     123 45      
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#21

Re: Dateiaustausch zwischen clientsocket und serversocket..^

  Alt 8. Okt 2007, 17:57
Nein, nimm nicht SizeOf, da kommt sowieso immer vier raus. Nimm Stream.Size.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
cRayZo

Registriert seit: 30. Jul 2007
156 Beiträge
 
Delphi 6 Personal
 
#22

Re: Dateiaustausch zwischen clientsocket und serversocket..^

  Alt 8. Okt 2007, 18:11
okay
Delphi-Quellcode:
var size:integer;
(...etc)
bitmap.SaveToStream(Stream);
size:=stream.Size;
(senden...etc)
wenn ich die Länge vorher aber in einem Sendtext übertrage, gehts ja nicht, weil
Zitat von ---> Muetze1:
Wenn du noch nicht fertig alles empfangen hast, dann würdest du mit ReceiveText sogar die Daten als string bekommen...
soll ich die länge des streams also in den stream selbst, an den Anfang setzen oder wie. Stell ich mir schwer umsetzbar vor
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#23

Re: Dateiaustausch zwischen clientsocket und serversocket..^

  Alt 8. Okt 2007, 18:27
Du sendest auf Serverseite erstmal die Größe mit SendBuf und dann den eigentlichen Stream mit SendStream. Auf der Clientseite prüfst du, ob die Übertragung schon begonnen hat - wenn nein, dann liest du die Größe und speicherst sie global. Andernfalls liest du mit deiner eigenen Methode (Puffer allozieren, lesen und in den Stream speichern) die Daten aus und prüfst, ob du die Gesamtgröße schon erreicht hast.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von Jens Schumann
Jens Schumann

Registriert seit: 27. Apr 2003
Ort: Bad Honnef
1.644 Beiträge
 
Delphi 2009 Professional
 
#24

Re: Dateiaustausch zwischen clientsocket und serversocket..^

  Alt 8. Okt 2007, 18:29
Hallo,
ich habe das Gefühl das hier mit "nicht blockierenden Socktes" gearbeitet wird.
Ich empfehle Dir die Komponenten in den "blockierenden Modus" zu schalten und die Übertragung
mit TWinSocketStream zu realisieren. Dann lösen sich alle hier genannten Probleme in Luft auf.
Die speicherst alles was Du Üertragen möchtest in einen Stream der dann mit TWinSocketStream gesendet wird.
Das Bitmap könntest Du dann mit TBitmap.SaveToStream(aWinSocketStream) senden.

Für die serverseitige ClientExecute Methode gibt es sogar ein Beispiel in der OH.
I come from outer space to save the human race
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#25

Re: Dateiaustausch zwischen clientsocket und serversocket..^

  Alt 8. Okt 2007, 18:56
Zitat von cRayZo:
also kann ich im server, wenn ich das Bild komplett geladen habe (sprich nach dem screenshot) einen sizeof machen? das müsste doch noch gehen oder?
SizeOf() liefert die Grösse eines Typs/Variable, welchen diese belegt im Speicher. Eine Instanz ist intern ein Pointer... bla blubb, siehe oben ... und liefert von daher immer 4 - weil 4 Bytes ist ein Pointer auf einem 32 Bit System/Compiler gross. (auch hier: siehe zuvor).

Stream.Size ist schon die richtige Antwort von Apollonius. Und zu deinem Problem mit dem SendText: Sende die Grösse einfach nicht in Textform (also als String) sondern als Binäre Daten. Dann ersparst du dir einfach das Umwandeln in den String und zurück und vor allem: du hast eine definierte Länge. Die Grösse eines LongInt/Int64/Char/Byte etc sind immer gleich gross bei dem gleichen Compiler und Zielsystem, weil sonst könnte der Compiler schlecht beim Erstellen des Programmes den Speicherplatz für Variablen vorhalten. Von daher wäre das eine gute Lösung.

Soviel zur Theorie, nun zum Code: Die Grösse dieser Variablen bzw. des Typs ermittelst du - tada - mit SizeOf(). Dieses würde dir z.B. für LongInt 4 Bytes liefern und für Int64 sogar 8 Bytes. Damit hättest du die Gewissheit, dass du immer nur (bei Nutzung eines LongInt's) 4 Bytes vorne die Grösse sind und alles nachfolgende schon die Stream-Daten.

Delphi-Quellcode:
var
  lLen: LongInt;
begin
  ...
  // Bitmap sichern in Stream, etc
  ...
  lLen := Stream.Size
  Socket.SendBuf(lLen, SizeOf(lLen));
  Socket.SendStream(Stream);
end;
Auf der Gegenseite einfach die Länge auslesen und dann damit arbeiten. Und damit du z.B. unterscheiden kannst, ob du nun das erste Mal versuchst Daten zu lesen und somit erstmal die 4 Bytes Streamgrösse auslesen musst oder ob es schon Stream-Daten sind, kannst du dich ja an deinem Empfangsstream orientieren: ist er schon angelegt, dann weisst du um die Länge, wenn nicht, dann erstmal diese auslesen...

Und das mit dem Empfangen der Länge solltest du mit dem Codeschnipsel gut selbst hinbekommen.

@other: Ja, ich hätte auch alles einfach mit Integer erklären können, aber ich bezog mich darauf, dass die Datentypen bei den gleichen Compilern und Zielsystemen gleich gross sind. Leider wächst aber Integer (generischer Ganzzahl-Typ) mit und wird bei einem 64-Bit Compiler (Delphi "Commodore", Winter 2008) auch 64 Bit gross sein, von daher wollte ich diesen Fakt nicht auswälzen und habe LongInt genommen, weil das definitiv 32 Bit gross bleibt.
  Mit Zitat antworten Zitat
cRayZo

Registriert seit: 30. Jul 2007
156 Beiträge
 
Delphi 6 Personal
 
#26

Re: Dateiaustausch zwischen clientsocket und serversocket..^

  Alt 10. Okt 2007, 18:38
okay, wieder scheiterts am Vokabular
ich hab mir versucht irgendwie trotzdem zu helfen
(trau mich ja fast ned das zu posten )

hier für den empfänger (Client)
Delphi-Quellcode:
begin
  iLen := Socket.ReceiveLength;
  GetMem(Bfr, iLen);
  try
    Socket.ReceiveBuf(Bfr^, iLen);
    FStream.Write(Bfr^, iLen);

    if FileExists('c:\teststream.bmp')
    then begin
                if x=Fstream.Size
                then image1.Picture.Bitmap.LoadFromStream(Fstream)end
    else begin x:=strtoint(copy(inttostr(Socket.ReceiveBuf(Bfr^, iLen)),0,4)); // * weiter unten -->
    FStream := TFileStream.Create('c:\teststream.bmp', fmCreate or fmShareDenyWrite); end;
  finally
    FreeMem(Bfr);
  end;

//*bestimmt viel leichter^^ aber ich kenn nur copy und copy geht nunmal soweit ich weiß nur mit string^^
end;
kanns Programm übrigens ohne Fehler starten, aber beim sendeversuch kommt ein Fehler.. (iwie auch klar)
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#27

Re: Dateiaustausch zwischen clientsocket und serversocket..^

  Alt 10. Okt 2007, 20:10
Ok, dann doch mal der Code beim Client:

1. Eine Variable vom Typ TStream im private Abschnitt der Form deklarieren (für die Daten) und dazu eine Variable vom Typ Integer, welche die Grösse der Daten hält.
Delphi-Quellcode:
  xxx = class(TForm)
  ...

  private
    FStream: TStream;
    fStreamDataSize: Integer;
  ...
  end;
2. Empfangsroutine: OnClientRead
Delphi-Quellcode:
procedure xxx.ClientSocket1ClientRead(...)
var
  iLen: Integer;
  Bfr: Pointer;
begin
  if not assigned(FStream) then // noch keine Übertragung bisher, Stream ist nil
  begin
      // Ok, dann müssten wir erstmal schauen und die Grösse des folgenden Streams
      // auslesen. Dazu erstmal schauen, ob wir die Grösse bisher überhaupt komplett empfangen haben...
    if Socket.ReceiveLength >= SizeOf(fStreamDataSize) then
    begin
        // dann nun die Grösse einlesen
      Socket.ReceiveBuf(fStreamDataSize, SizeOf(fStreamDataSize));

        // dann Stream anlegen
      FStream := TMemoryStream.Create;
    end;
// else
// Exit; // ok, dann weiter warten, bis wir die Grösse komplett empfangen haben (Code unnötig)
  end;

    // ok, hier nun, wenn der Stream existiert, einlesen der Daten die empfangen wurden und Schreiben in den Stream
  if assigned(FStream) then
  begin
    iLen := Socket.ReceiveLength;

      // Ok, nur die Daten auch empfangen, die zu unserem Stream gehören. Also schauen wieviel wir noch vom Stream einlesen
      // müssen...
    iLen := Min(fStreamDataSize, iLen);

    GetMem(Bfr, iLen);
    try
      Socket.ReceiveBuf(Bfr^, iLen);

// fStreamDataSize := fStreamDataSize - FStream.Write(Bfr^, iLen); // beides gleich - schreiben der Daten
      Dec(fStreamDataSize, FStream.Write(Bfr^, iLen); // und Variable fStreamDataSize runterzählen um die
                                                                         // empfangenen und geschriebenen Daten...
    finally
      FreeMem(Bfr);
    end;

    if fStreamDataSize = 0 then // alles empfangen?
    begin
        // Positionszeiger zurücksetzen
      FStream.Position := 0;

        // Image einlesen
      Image1.Picture.Bitmap.LoadFromStream(FStream);
    
        // MemoryStream freigeben und auf nil setzen (wegen den If Assigned() Abfragen)
      FreeAndNil(FStream);
    end;
  end;

    // wenn er hier ankommt und ReceiveLength() ist immernoch > 0, dann sind noch Daten im Stream, die aber nicht
    // mehr zum Bild gehören - oder - wir haben die Grösse der Streamdaten noch nicht empfangen.
end;
3. Beim Server folgendes um die Grösse vorne weg zu senden:
Delphi-Quellcode:
var
  lLen: Integer;
  lStream: TStream;
begin
  lStream := TFileStream.Create('c:\testbild.bmp', fmOpenRead);

  lLen := lStream.Size; // grösse Stream ermitteln
  Socket.SendBuf(lLen, SizeOf(lLen)); // Grösse senden

  Socket.SendStream(lStream); // dann das Bild hinten dran...
end;
So, soweit zur Theorie. Alles hier im Forumfenster geschrieben, sollte aber so laufen...
  Mit Zitat antworten Zitat
cRayZo

Registriert seit: 30. Jul 2007
156 Beiträge
 
Delphi 6 Personal
 
#28

Re: Dateiaustausch zwischen clientsocket und serversocket..^

  Alt 10. Okt 2007, 20:17
jo ist gebongt und jetzt?..
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#29

Re: Dateiaustausch zwischen clientsocket und serversocket..^

  Alt 10. Okt 2007, 20:27
Zitat von cRayZo:
jo ist gebongt und jetzt?..
Sorry, war noch beim tippen - hatte mich nur verdrückt mit ALT-S anstatt ALT-D...
  Mit Zitat antworten Zitat
cRayZo

Registriert seit: 30. Jul 2007
156 Beiträge
 
Delphi 6 Personal
 
#30

Re: Dateiaustausch zwischen clientsocket und serversocket..^

  Alt 10. Okt 2007, 20:48
achso, kein Problem, ja vielen Dank auf jeden fall!!!
einmal nur ne klammer vergessen(is ja np )
mein delphi gibt den Ausdruck 'min' nur als nicht definiert zurück.iLen := Min(fStreamDataSize, iLen); das versteh ich aber nicht, ist doch eine Funktion
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 5     123 45      


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 06:17 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