Autor |
Beitrag |
GlobalImpact
Hält's aus hier
Beiträge: 9
|
Verfasst: Fr 28.07.06 13:35
Hallo,
ich würde gerne ein Programm schreiben, das Dateien per UDP versenden kann, ich habe mich schon durch alle möglichen Foren gewühlt und oft gelesen, dass UDP nicht unbedingt sinvoll ist zum Versenden von Dateien, ich würde es jedoch nur für mp3s nutzen, d.h. es stört nicht, wenn ein paar KB verloren gehen.
Ich hab das ganze mal mit Indy angefangen:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, WinSock, UdpSockUtil, IdUDPServer, IdBaseComponent, IdComponent, IdUDPBase, IdUDPClient, IDSocketHandle, IdGlobal, IDStream;
type TForm1 = class(TForm) Button1: TButton; Server: TIdUDPServer; Client: TIdUDPClient; procedure ServerUDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject);
const
private public end;
var Form1: TForm1; zaehler : integer; implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); begin Server.Active := true; Client.Active := true; end;
procedure TForm1.Button1Click(Sender: TObject);
var Buffer : Array [0..4096] of Byte; Stream : TMemorystream; begin
Stream := TMemorystream.Create; Stream.LoadFromFile('D:\bild.jpg'); Stream.ReadBuffer(Buffer, sizeof(Buffer)); Client.SendBuffer(Buffer,sizeof(Buffer));
Stream.free; end;
procedure TForm1.ServerUDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
var MStream : TMemorystream;
begin
MStream := TMemorystream.create;
MStream.LoadFromStream(ADATA) ; Mstream.SaveToFile('D:\bild02.jpg');
end;
end. |
Mein Problem an der Sache ist jetzt, dass das senden zwar funktioniert, aber dass immer nur (logischerweise) der Inhalt des Puffers versendet wird und ich dann immer nur 4KB von der Datei übertrage, d.h. beim Bild nur ein ca. achtel sichtbar ist.
Wie kann ich jetz stückchenweise das Bild übertragen und dann beim Empfänger zusammenfügen?
Danke für die Info
mfg
Global Impact
PS: Hab Indy 9
Moderiert von raziel: Code- durch Delphi-Tags ersetzt
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Fr 28.07.06 15:38
Moin!
Vorab: Bitte verwende die Delphi-Tags für den Code, damit das Syntaxhighlighting aktiv ist.
Jetzt zu deinem Problem(en).  Was du dir da ausgesucht hast, ist gar nicht so einfach...
Kannst du denn Dateien über eine TCP-Verbindung übertragen? Wenn du das noch nie gemacht hast, solltest du erst mal damit "üben", damit dir die grundsätzliche Vorgehensweise beim Dateitransfer wirklich klar ist. Bei UDP kommen nämlich noch eine ganze Menge weiterer Probleme auf dich zu...
Was du beachten mußt:
- UDP hat eine Maximalgröße für Datagramme (Pakete), die bei 512 Bytes liegt. Übergibst du der Sender-API mehr, stückelt die das schon auf... (was nicht immer so besonders sinnvoll ist)
- UDP-Pakete können einfach auf dem Weg verloren gehen, du merkst nichts davon
- Die Empfangsreihenfolge ist nicht zwingend die gleiche, wie beim Senden!
- Wenn du auf Datenkonsistenz angewiesen bist (Dateitransfer), dann mußt du für eine Sicherungsschicht sorgen (nachhalten, welche Pakete in welche Reihenfolge gehören und fehlende nachfordern -> schau mal nach "Sliding-Window-Protokoll")
- Wenn du streamen willst, was als fehlertolerant definiert ist, dann brauchst du keine Sicherungsschicht, mußt aber mit "Löchern" im Datenstrom umgehen können.
Die Frage ist also: was genau willst du denn eigentlich machen?!
Wenn du dir über all die genannten Dinge ein paar Gedanken gemacht hast, dann kannste ja nochmal nachfragen, wenn du ein konkretes Code-Problem hast.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
GlobalImpact 
Hält's aus hier
Beiträge: 9
|
Verfasst: Fr 28.07.06 16:00
Erstmal Danke für die Antwort.
Ich habe mich vorher schon über die Eigenschaften von UDP, was die Fehler betrifft (Datenpakete werden in anderer Reihenfolge gesendet...), schlau gemacht, hab halt in diesem und anderen Foren Tutorials und Beiträge gelesen und möchte selbst gerne ausprobieren, wie das ganze mit UDP funktioniert.
Ich habe schon ein Programm geschrieben, mit dem Dateien über TCP übertragen werden (TIDTCPSockets von Indy verwendet). Da konnte ich die Dateien leicht via sendstream verschicken.
Die Schwierigkeit, die ich jetz bei UDP habe, ist, dass ich die Datei über einen Puffer verschicken muss.
Toll wäre natürlich, wenn jemand ein Tutorial zu dem Thema wüsste (Ich habe bereits ein UDP Tutorial gefunden, das beschäftigt sich aber nur mit dem senden von Text, was mir nicht weiterhilft, einen Chat über UDP habe ich bereits bewerkstelligt).
Ich bin Dankbar für jede Info, die ich über die UDP Indys und Sendbuffer kriege.
Vielleicht kann mir ja irgendjemand weiterhelfen.
Danke nochmal
mfg
Global Impact
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Fr 28.07.06 16:37
Moin!
GlobalImpact hat folgendes geschrieben: | Ich bin Dankbar für jede Info, die ich über die UDP Indys und Sendbuffer kriege. |
Was ist denn konkret dein Problem damit?  Wie .SendBuffer funktioniert, sollte dir klar sein, wenn du es schon mit einer TCP-Verbindung geschafft hast.
IMHO liegt dein Problem nicht beim Umgang mit den Indies, sondern beim Programmkonzept...  Du kannst halt per UDP immer 512 Bytes am Stück versenden, Streams direkt zu verwenden, kannste vergessen (weil keine Protokoll-Infos drin sind), fertig.
Also, wo ist genau das Problem bei dir?
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
GlobalImpact 
Hält's aus hier
Beiträge: 9
|
Verfasst: Fr 28.07.06 17:08
Mein Problem is, dass ich bei meinem TCP Programm die Dateien im ganzen verschicken konnte, bei den UDP Sockets aber über sendbuffer schicken muss.
Ich schaffs ja mit Sendbuffer Daten zu senden, ich kann halt nur nicht 5 MB oder sowas in einen Puffer schicken, weil scheinbar mein Array of Bytes, den ich verschicke nicht so viel fassen kann.
Delphi-Quelltext 1:
| var Buffer : Array [0..4096] of Byte; |
D.h. ich muss die Datei scheinbar Stückchenweise vom client aus schicken und am server wieder zusammensetzen.
Und das ist es was mir die Probleme macht.
Ich habs auf verschiedene Arten probiert, nur entweder kam nur Müll an oder gar nix: z.B. so:
Delphi-Quelltext 1: 2: 3: 4: 5:
| Stream := TMemorystream.Create; Stream.LoadFromFile('D:\bild.jpg'); Stream.ReadBuffer(Buffer, sizeof(Buffer)); Client.SendBuffer(Buffer,sizeof(Buffer)); Stream.position := stream.position + 4096; |
Wie kann ich also die Datei in Teile verschicken, hab leider keinen Plan wie ich das anstellen soll.
mfg
Global Impact
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Fr 28.07.06 18:12
Moin!
GlobalImpact hat folgendes geschrieben: | Ich schaffs ja mit Sendbuffer Daten zu senden, ich kann halt nur nicht 5 MB oder sowas in einen Puffer schicken, weil scheinbar mein Array of Bytes, den ich verschicke nicht so viel fassen kann. |
Du weißt nicht wirklich, was du da so tust, oder...  Das hat nix mit dem Buffer zu tun, du kannst abgesehen davon eh nicht mehr als 512 Bytes am Stück in ein UDP-Paket tun.
Mach das doch mal so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| var Buffer: String; Stream: TFileStream; Len: Int64; begin SetLength(Buffer,512); Stream := TFileStream.Create('datei.txt',fmOpenRead or fmShareDenyWrite); Len := Stream.Size; while (Len > 0) do begin if (Len >= 512) then begin Stream.Read(PChar(Buffer)^,512); Client.SendBuf(PChar(Buffer)^,512); Dec(Len,512); end else begin Stream.Read(PChar(Buffer)^,Len); Client.SendBuf(PChar(Buffer)^,Len); Len := 0; end; end; Stream.Free; |
Damit kannst du die Datei in 512-Bytes-Blöcken senden. Es sollte sich übrigens nicht um eine strukturierte Datei handeln (wie z.B. JPG), da du die Integrität des Datenstromes (wie oben realisiert) nicht sicherstellen kannst. Dazu bräuchtest du ein Protokoll.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
GlobalImpact 
Hält's aus hier
Beiträge: 9
|
Verfasst: Sa 29.07.06 19:14
Danke für die Antwort.
Hab den Quelltext an mein Programm angepasst und es geht!!
Danke nochmal
mfg
Global Impact
|
|
GlobalImpact 
Hält's aus hier
Beiträge: 9
|
Verfasst: Sa 29.07.06 22:31
Hallo nochmal, scheinbar gibts doch noch ein Problem.
Ich probier jetz seit 1 Tag und einer Nacht rum und kriegs net hin.
Ich kann zwar jetz Dateien versenden, aber wenn diese 8,5 KB (genauer 8704 Bytes) übersteigen, dann werden eben nur die genannten 8,5 KB gesendet und der Rest weggelassen.
Ich hab bereits den Buffer der Indysockets vergrößert, hat auch nix geholfen, hab ewig mit den Streams rumprobiert ...
Also versenden tut er mirs scheinbar noch, ich hab mir mit showmessage immer die Position des Strings anzeigen lassen, der versendet wird, und in dem Stream geht die Position in 512er Schritten bis zum Ende.
Beim empfangen is aber nach 8704 Bytes schluss.
Das is der Code mit dem ich empfang:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| procedure TForm1.ServerUDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
begin
Adata.readbuffer(PChar(Puffer)^, 512) ; fs.Writebuffer(PChar(Puffer)^, 512) ;
showmessage(inttostr(fs.size));
end; |
FS ist ein TMemorystream.
Adata, der Stream aus dem UDPServer.
Ich blick nicht warum immer nur diese 8704 Bytes angenommen werden.
Weiss jemand Rat?
Danke für die Hilfe
mfg
Global Impact
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: So 30.07.06 23:48
Moin!
Schau doch mal hier, vielleicht kommst du damit ja besser zurecht, als mit den Indies.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
|