Autor Beitrag
Seraph
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 163

Windows.:siXPack:.
Delphi7 Professional
BeitragVerfasst: Fr 31.10.08 19:21 
Hi Leute!

Ich beschäftige mich zur Zeit mit der Dateiübertragung zwischen Sockets!
Ziel ist es, eine Datei zwischen Client(TClientSocket) und Server(TServerSocket) zu übertragen ohne NichtStandard-Komponenten zu verwenden!

Ja denk ich mir: Kein Thema, oder doch?

Mein Denkansatz war der! Ich mache eine Schablone als Array of Bytes und lege diese Blockweise über meine Datei. Danach verschicke ich den so entstandenen ByteBuffer via Socket.SendBuf();
Auf der Serverseite hole ich via Socket.ReceiveBuf() das ganze wieder in ein Array of Bytes und schreibe is wieder Blockweise in eine Datei!

So der bisherige Code:

ausblenden volle Höhe 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:
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:
//Client:----------------------------------------

//....

type TFileBlocks = Array [0..1024 - 1of Byte; //meine Schablone

var
  Form1: TForm1;
  FileBuffer: TFileBlocks;
  SendFile: file;

implementation


//...

procedure SendFileBlock(StartBlock: Integer);
var
 iReadCount: Integer;
begin
 ZeroMemory(@FileBuffer, 0);

 if(not eof(SendFile))
 then begin
  BlockRead(SendFile, FileBuffer, sizeof(FileBuffer), iReadCount);
  Form1.ClientSocket1.Socket.SendBuf(FileBuffer, iReadCount);
 end else begin
  CloseFile(SendFile);
  CloseFile(tFile);
  Form1.ClientSocket1.Socket.SendText('endoffile'); //server sendet 'next' bis 'endoffile'
 end;
end;

procedure TForm1.SendFileBttnClick(Sender: TObject);
begin
  ClientSocket1.Socket.SendText('sending:Test.file'); //leitet das senden ein
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
 RecText: String;
begin
 RecText := Socket.ReceiveText;
 
 //hier die Kommunikation zwischen Server und Client
 if(RecText = 'ready')//der Server schickt 'ready', wenn die Datei geschickt werden kann 
 then begin
  AssignFile(SendFile, Path.Text);
  Reset(SendFile, 1);

  SendFileBlock(); //1. Block schicken (siehe oben)
 end else if(RecText = 'next')//wenn der Server 'next' schickt...
 then begin
  SendFileBlock(); //nächsten Block schicken (siehe oben)
 end;
end;
//__________________________
//__________________________


ausblenden volle Höhe 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:
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:
//Server:--------------------------------------------------

//...

type TFileBlocks = Array [0..1024of Byte;
pBuffer = ^TFileBlocks;

var
  Form1: TForm1;
  FILE_NAME: String;
  TargetFile: file;

implementation


//...

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
 RecText: String;
 BlockCount, WriteCount: Integer;
 RecLength: Integer;
 bBuffer: Array of Byte;
 pFileBuffer: pBuffer;
begin
 RecLength := Socket.ReceiveLength;
 RecText := Socket.ReceiveText;
 
 //BITTE KEIN KOMMENTAR ZU MEINEN ABFRAGEN ;-)
 //ICH MACH DAS EIGENTLICH ÜBER EINE EXPLODE FUNC,
 //ABER ICH GLAUBE DASS SIE HIER NUR ZUR ALLGEMEINEN VERWIRRUNG BEITRAGEN WÜRDE
 if(MidStr(RecText, 1, StrLen(PChar('sending:'))) = 'sending:')
 then begin
  FILE_NAME := MidStr(RecText, StrLen(PChar('sending:')) + 1, StrLen(PChar(RecText)) - StrLen(PChar('sending:')));

  AssignFile(TargetFile, 'C:\' + FILE_NAME);
  Rewrite(TargetFile, 1);

  ServerSocket1.Socket.Connections[0].SendText('ready');
 end else if(RecText = 'endoffile')
 then begin
   CloseFile(TargetFile);
   ShowMessage('ENDE');
 end else begin
  ZeroMemory(pFileBuffer, 0);

  GetMem(pFileBuffer, RecLength);

  Socket.ReceiveBuf(pFileBuffer , BlockCount);
  
  BlockWrite(TargetFile, pFileBuffer^, RecLength, WriteCount);
  ServerSocket1.Socket.Connections[0].SendText('next');
 end;
end;


Es ist ja nicht so dass jetzt in der Datei nix drin steht!

Der Inhalt der orginalfile ist:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
#EXTM3U
#EXTINF:326,Black Eyed Peas - My Humps
Personal Dats\Mucke2\005 - Black Eyed Peas - My Humps.mp3
#EXTINF:225,Rammstein - Benzin
Personal Dats\Mucke2\006 - Rammstein - Benzin.mp3
#EXTINF:213,Sean Paul - We Be Burnin'
Personal Dats\Mucke2\008 - Sean Paul - We Be Burnin'.mp3
#EXTINF:237,20 Pink - Just like a Pill
Personal Dats\Mucke2\01 - 20 Pink-Just like a Pill.mp3
#EXTINF:207,Jack Johnson - Better Together
Personal Dats\Mucke2\01 - Better Together.mp3
....

Ja das ist eine Winamp Playlist ;-)


Das ist das, was dabei raus kommt: :-(

1. Variante:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
òÍ
(

54,Michael Jackson - Wanna Be Startin Somethin 2008
Personal Dats\Mucke2\Top100_4_08\067-michael_jackson_-_wanna_be_startin_somethin_2008-ministry.mp3
#EXTINF:215,Colbie Caillat - The Little Things
Personal Dats\Mucke2\Top100_4_08\068-colbie_caillat_-_the_little_things-ministry.mp3
#EXTINF:203,Kanye West ft Chris Martin - Homecoming
Personal Dats\Mucke2\Top100_4_08\069-kanye_west_ft_chris_martin_-_homecoming-ministry.mp3
#EXTINF:233,Amy Winehouse - Valerie
...


2. Variante ist dann Binäres gedöns!

Es sieht immer anders aus! :-(

Huhuhuuuuuu..... Ich hock dran und könnt kotzen!


Danke im Voraus und Gruß,
Seraph


Ps.: @Narses: Dein Tutorial hab ich schon gesehen (Respekt übrigens) aber das ist mächtiger als das was ich benötige!

Es muss doch auf diesem Weg gehen!


Zuletzt bearbeitet von Seraph am Mo 03.11.08 14:24, insgesamt 1-mal bearbeitet
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1336
Erhaltene Danke: 119

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Fr 31.10.08 20:25 
Das Senden von binären Daten ist nicht ganz so einfach wie es mit Texten läuft, was im übrigen auch ginge.
Du könntest die Datei als einzelne Strings übertragen, die ja intern nichts weiter als eine Folge von Bytes sind.
Aber besser ist es natürlich es mit SendBuf zu erledigen.
Als erstes solltest du der anderen Seite natürlich mal mitteilen wie groß die Datei ist die du übertragen willst.
Das erleichtert es dir hinterher das zusammenbauen. Da du dann weist wann nichts mehr kommen kann was mit der Datei zu tun hat.
Des weiteren solltest du beim addressieren des Puffers mit dem du arbeitest die Addresse der ersten Speicherstelle angeben:
ausblenden Delphi-Quelltext
1:
2:
  BlockRead(SendFile, FileBuffer[0], sizeof(FileBuffer), iReadCount);
  Form1.ClientSocket1.Socket.SendBuf(FileBuffer[0], iReadCount);

Beim Lesen machst du das ganze dann genauso. Denn das was du da schreibst deutet darauf hin das du dir an irgend einer Stelle Daten einhandelst die irgendwo im Speicher stehen, nur nicht dort wo du es willst.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
Seraph Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 163

Windows.:siXPack:.
Delphi7 Professional
BeitragVerfasst: Mo 03.11.08 14:23 
Danke für deine schnelle Antwort Sinspin,
aber das Funktioniert auch nicht!

Der Buffer muss doch so wie er Deklariert wurde [0..XXXX] passen oder etwa nicht?

Bin echt ratlos langsam!

Ich scheine so nah dran zu sein, aber der letze Funke will net überspringen!

Die größe der Datei passt exakt!
Aber der Inhalt ist größtenteils für den *popo*!

Währe cool, wenn mir noch jemand den letzten Hinweis geben könnte!

Danke im Voraus,
Seraph

p.s.: wenn ich mir den Buffer mit ReadText ausgeben lasse, dann erscheinen die Blöcke exakt richtig und vollständig!
Seraph Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 163

Windows.:siXPack:.
Delphi7 Professional
BeitragVerfasst: Mi 12.11.08 12:37 
Titel: Push
Klappt bis heute nicht!

Keiner ne Idee?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19340
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 12.11.08 13:50 
Moment mal:
ausblenden Delphi-Quelltext
1:
2:
3:
  ZeroMemory(pFileBuffer, 0);

  GetMem(pFileBuffer, RecLength);
Du füllst da Speicher mit 0, aber was ist das denn für Speicher? Du hast pFileBuffer ja noch gar nicht initialisiert.

Ich vermute du überschreibst da Speicher, was sich bei später ausgeführtem Code dann bemerkbar macht.
Volle
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 19



BeitragVerfasst: Mi 12.11.08 14:11 
Hoi,

bin mir grad nich sicher aber musst du nich aus

ausblenden Delphi-Quelltext
1:
BlockRead(SendFile, FileBuffer, sizeof(FileBuffer), iReadCount);					


das hier machen?
ausblenden Delphi-Quelltext
1:
BlockRead(SendFile, FileBuffer, 1024*sizeof(FileBuffer[0]), iReadCount);					


gibt sizeof() in diesem fall nich einfach nur die groesse eines Pointers aus?
Hoffentlich erzaehl ich hier grad kein mist ....

cYa

[edit]
ich hab mist erzaehlt ... :<
vergiss es .. hab da was verwechselt ...
[/edit]