AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi wie versende ich mit tclient/serversocket eine datei?
Thema durchsuchen
Ansicht
Themen-Optionen

wie versende ich mit tclient/serversocket eine datei?

Ein Thema von gandime · begonnen am 9. Sep 2006 · letzter Beitrag vom 11. Feb 2007
Antwort Antwort
Seite 3 von 4     123 4      
flossinger

Registriert seit: 22. Aug 2005
Ort: südlich der Alpen
109 Beiträge
 
Delphi 5 Standard
 
#21

Re: wie versende ich mit tclient/serversocket eine datei?

  Alt 10. Sep 2006, 18:13
ja wie meinst du die Frage nach dem Teilen und Zusammensetzen. Es wurde schon ein Beispiel gepostet, das völlig korrekt teilt und zusammensetzt. Damit ist deine Frage ja schon beantwortet. Es hat wenig Sinn, so etwas zu wiederholen, nachdem dir das nicht geholfen hat. Welchen Teil hast du nicht verstanden, welchen Teil hast du nicht nach vollzogen. Warum läuft ein funktionierendes Beispiel bei dir nicht?
Von welchem der Verarbeitungsschritte sprichst du jetzt? Was funktioniert bei deinen Testdaten und was genau funktioniert nicht?

Hast du schon herausgefunden, was dein Programm jetzt GENAU macht? Die entsprechenden Rückfragen wurden dir im Thread gestellt und deine Antworten stehen noch aus. Du hast schon eine Anleitung erhalten, WIE du das herausfinden kannst und wie du damit deine Fragen konkretisieren kannst.

Denkst du, du bekommst viele Antworten, wenn du die erteilten Antworten offensichtlich missachtest? Hast du eigentlich die Vorstellung dass sich viele Menschen danach drängen, eine Antwort zu geben, die voraussichtlich ignoriert wird? Überleg das mal in einer ruhigen Minute.

grüsse,
der flossinger
  Mit Zitat antworten Zitat
gandime
(Gast)

n/a Beiträge
 
#22

Re: wie versende ich mit tclient/serversocket eine datei?

  Alt 10. Sep 2006, 21:19
so das habe ich jetzt auch hinbekommen mit dem splitten usw. aber wie weiss das prog das die datei komplett ist damit es freeandnil(fstream) machen kann?
  Mit Zitat antworten Zitat
flossinger

Registriert seit: 22. Aug 2005
Ort: südlich der Alpen
109 Beiträge
 
Delphi 5 Standard
 
#23

Re: wie versende ich mit tclient/serversocket eine datei?

  Alt 11. Sep 2006, 14:50
gratuliere,

entweder ist zu Beginn die Anzahl der Bytes mitgeteilt worden, oder es gibt ein EOF Zeichen, das im File selbst sicher nicht vorkommt.

Erstere Variante verwendet beispielsweise das http Protokoll, bekanntlich: Content-Length: nnnn.

Letztere Variante eignet sich nur für bestimmte Files. Ein http header beispielsweise wird bekanntlich durch crlfcrlf beendet. crlfcrlf kann dazu verwendet werden, weil es im header selbst nie vorkommen kann. Anderes bekanntes Beispiel: Bei der Übertragung von emails wird crlf.crlf verwendet.

Dritte Variante: Es wird jedes mal vom Sender eine EOF sequenz gesucht, die im File nicht vorkommt, und dem Empfänger mitgeteilt.

Am besten ist es, du schaust dir die Protokolle in den rfcs an und baust etwas nach, das deinem beabsichtigten Einsatz am besten dient. Hat alles seine Vor- und Nachteile und es kommt ganz darauf an.

grüsse,
der flossinger
  Mit Zitat antworten Zitat
Arnulf

Registriert seit: 28. Okt 2004
Ort: Wien
271 Beiträge
 
#24

Re: wie versende ich mit tclient/serversocket eine datei?

  Alt 5. Feb 2007, 21:59
Zitat:
3. Wenn die Datei grösser ist, dann hast du beim Empfangen (sowie zZ noch beim Senden) ein Problem, da du soviel Speicher alloziierst. Besser wäre hier eine feste Puffergrösse und entsprechend immer Blockweise einlesen und senden bis alle Daten empfangen/gesendet wurden.
Tja ich denke genau an dem problem häng ich gerade.
Ich kann natürlich den stream zerlegen und die daten schön langsam senden.
Die frage ist aber wie langsam muß ich die daten schicken? - woher weiß ich wieviel puffer ich noch am socket hab bzw. wieviel schon weggeschickt wurde.

das sorgt bei mir noch für etwas verwirrung - ich hätte nämlich vor ein video zu streamen und das geht recht langsam von statten.

hoffe es gibt dazu noch tips
Arnulf
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#25

Re: wie versende ich mit tclient/serversocket eine datei?

  Alt 6. Feb 2007, 00:17
Lese deinen Puffer voll und schreibe ihn in den Stream. Und dies so lange, bis du die gesamte Datei/gesamten Daten im Stream hast.
  Mit Zitat antworten Zitat
Arnulf

Registriert seit: 28. Okt 2004
Ort: Wien
271 Beiträge
 
#26

Re: wie versende ich mit tclient/serversocket eine datei?

  Alt 7. Feb 2007, 10:55
Zitat:
Lese deinen Puffer voll und schreibe ihn in den Stream. Und dies so lange, bis du die gesamte Datei/gesamten Daten im Stream hast.
sorry wenn ich das nicht gleich verstehe.

ich soll den stream ganz einlesen und auch in den puffer - damit meinst wohl den pointer mit der size?

Delphi-Quellcode:
            AStream := TfileStream.Create(income, fmOpenRead or fmShareDenyWrite );
            try
               buffer := AllocMem(AStream.Size);
               AStream.Read(buffer^,AStream.Size);
und ja jetzt könnte ich von buffer weg nur teile in die sendstream methode schreiben.
die frage ist aber wie viel (bytes) kann in gleichzeit in die sendstream methode jagen ohne einen cache overflow im
socket zu bekommen.
Und wie weiß ich wann ich sendstream wieder aufrufen kann um den rest zu schicken?
Ich weiß ja nicht wie voll der cache ist.
also im prinzip das hier in packerl auf geteilt und hald langsamer in den stream geschickt - aber wenn ich da eine schleife mache, dann mach ich den cache ja wieder voll - oder irr ich mich da?

Delphi-Quellcode:
               with Socket do
                    SendBuf(buffer^, AStream.Size);
               finally
                      FreeMem(buffer);
                      FreeAndNil(AStream);
               end;
mit ist schon klar dass ich bei Astream.Size die größe eingeben kann - und in einer schleife einfach packerweise mehr schicken kann - aber macht das einen unterschied? - ich weiß ja immer noch nicht wie voll der socket cache ist bzw. ob ich einen overflow bekomme wenn ich zu viel rein schreibe.
thx
Arnulf
  Mit Zitat antworten Zitat
Arnulf

Registriert seit: 28. Okt 2004
Ort: Wien
271 Beiträge
 
#27

Re: wie versende ich mit tclient/serversocket eine datei?

  Alt 7. Feb 2007, 11:09
ok sorry - ich habs gerade ausprobiert und es funktioniert wirklich.
wenn jemand weiß warum würde ich das gerne wissen...
was macht den unterschied wenn ich den stream in packerln zerleg oder als ganzes rein schreib.
wie groß dürfen die packerln maximal sein?
also warum funktioniert das

lg
Arnulf
Edit:
also ganz richtig funktioniert es nicht - kann aber nur vermutungen anstellen warum.
ich bekomm jetzt keinen fehler mehr wenn ich eine 700 mb datei wegschicke.
allerdings schreib ich einen minni webserver und der muß ja die verbindung immer wieder trennen.

scheinbar trennt er die verbindung aber zu früh - bevor die datei noch ganz rauf geladen ist.
hier liegt wohl das gleiche problem wie vorher - ich kann die verbindung nicht trennen bevor nicht alles
rauf geladen ist:

so schaut der code aus:
Delphi-Quellcode:
              try
               buffer := AllocMem(AStream.Size);
               for s := 1 to AStream.Size div Package do
                 begin
                      AStream.Read(Buffer^,Package);
                      Socket.SendBuf(buffer^,Package);
                      Sleep (50);
                      uploaded := s;
                      memo1.Lines.Add(inttostr(uploaded * package));
                 end;
                 Sleep(50);
                 if ((uploaded*Package) < AStream.Size)
                 then begin
                      last := AStream.Size - (uploaded * Package);
                      AStream.Read(Buffer^,last);
                      Socket.SendBuf(buffer^,last);
                      end;
               finally
                 FreeMem(buffer);
                 FreeAndNil(AStream);
               end;
        socket.close;
das socket.close dürfte einfach zu früh kommen - aber darüber hab ich keine kontrolle zumindestens keine die ich kenne.
lg
Arnulf
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#28

Re: wie versende ich mit tclient/serversocket eine datei?

  Alt 7. Feb 2007, 13:01
1. Der Buffer braucht nur "Package" gross sein - schliesslich nutzt du auch nur soviel von ihm.
2. Der Socket hat intern einen Puffer und füllt den immer nur bis zu seiner Maximalgrösse. Wenn du nun mit SendBuf() Daten hinein schreibst, dann gibt dir SendBuf() zurück, wieviel er davon in seinen internen Buffer aufgenommen hat. Daher muss du auch darauf resgieren und entsprechend auch mal Teile von deinem Buffer erneut dem SendBuf() übergeben.
Zitat von Delphi Hilfe:
Bei nicht-blockierenden Sockets werden die Daten an die WinSock DLL gesendet, die über eigene interne Puffer verfügt. Wenn WinSock weitere Daten akzeptieren kann, gibt SendBuf sofort die Anzahl der Byte in der Warteschlange zurück. Wenn der interne Puffer von WinSock den gesendeten Puffer nicht mehr aufnehmen kann, gibt SendBuf -1 zurück, und es werden keine Daten in die Warteschlange übernommen. In diesem Fall müssen Sie etwas warten, bis WinSock die sich bereits in der Warteschlange befindlichen Daten gesendet hat und es dann erneut versuchen.
3. Read() vom TStream gibt dir zurück, wieviele Bytes er ausgelesen hat. Somit kannst du leicht den Rückgabewert von Read() nutzen um ihn beim SendBuf() entsprechend anzugeben. Hierdrüber kannst du dir auch leicht deine letzte "Sonder-If-Abfrage" für das "Reste-senden" sparen.
4. Du hast selber schon geschrieben (fälschlicherweise wahrscheinlich), dass es noch die Methode SendStream() gibt. Diese erledigt alle von dir gesuchten Aufgaben asynchron. Du gibst ihr ein TStream Nachkomme (z.B. TFileStream) und sie kümmert sich um das Senden des Streams. Wenn der Stream erfolgreich gesendet wurde, dann gibt der Socket den Stream auch weider automatisch frei. Die SendStream() beinhaltet dein gesamten Code samt Warten etc. Du darfst nach der Übergabe der TStream Instanz diese nicht mehr weiter verwenden in deinem Programm, da der Socket in seinem Thread damit arbeitet.

PS: Und ja, so wie du es umgesetzt hast meinte ich es auch...
  Mit Zitat antworten Zitat
Arnulf

Registriert seit: 28. Okt 2004
Ort: Wien
271 Beiträge
 
#29

Re: wie versende ich mit tclient/serversocket eine datei?

  Alt 8. Feb 2007, 20:08
Ich verstehe - danke für deine genaue antwort.

Ich hab das ganze nochmal in java versucht weil ich in delphi damit nicht weiter gekommen bin.
Delphi-Quellcode:
             while ((len = is.read(buf)) != -1)
             {
              out.write(buf, 0, len);
              }
was in meinem fall genau garnichts gebracht hat... naja
jedenfalls verstehe ich jetzt warum ich mit sendstream immer so viele probleme hatte, weil ich den stream danach meistens gleich
wieder frei gegeben hab - und wenn der socket noch am senden war dann hatte das wohl ein jähes ende ...

jedenfalls wird mir hier einiges klarer - aber das löst mein problem nicht wirklich - leider.
irgendwie macht mich dieser streaming client von pinnacle noch wahnsinnig.
also wieder zurück zu delphi und weiter versuchen ..

Wenn ich das richtig verstehe, hab ich bei sendstream einfach keine kontrolle über den verlauf des sendens.
Ich weiß nicht wann er fertig ist und wieviel schon im puffer ist.
damit muß ich das eh manuell mit sendbuf machen damit kann ich wenigstens den stream genau kontrollieren ...

thx lg
Arnulf

PS: ja tatsächlich wer lesen kann ist klar im vorteil - und ich dachte da steht nichts vernünftiges drin
Zitat:
Note: The Stream passed as a parameter to SendStream becomes “owned” by the windows socket object. The Windows socket object frees the stream when it is finished with it. Do not attempt to free the stream after it has been passed as a parameter.
  Mit Zitat antworten Zitat
jokerfacehro
(Gast)

n/a Beiträge
 
#30

Re: wie versende ich mit tclient/serversocket eine datei?

  Alt 9. Feb 2007, 08:09
hallo,
da mich das Thema auch interessiert, hab ich grad ma fix ne funktion gebastelt,
die das hinkriegt.
es ist leichter als man denkt

zu erst senden wir alles per stream vom client:
Delphi-Quellcode:
procedure Button1Click(Sender: TObject);
var AStream:TFileStream;
begin
AStream := TFileStream.Create('hallo.txt', fmOpenRead or fmShareDenyWrite );
Clientsocket1.Socket.SendStream(AStream);
end;
so und jetz müssen wir das ganze nur noch am server empfangen
Delphi-Quellcode:
procedure TForm1.Server1Read(Sender:TObject;Socket:TCustomWinSocket);
begin
Memo2.Text:=Memo2.Text+Socket.ReceiveText;
end;
fertig
funktioniert wunderbar

man kann ja end EOF zeichen vereinbaren oder direkt danach die verbindung trennen
und dann per ondisconnect die datei schreiben
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 4     123 4      


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 00:13 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