Entwickler-Ecke

Internet / Netzwerk - Mit indy 9 eine .mp3 Datei senden (von server zu client)


pigfacejoe - Mo 30.10.06 00:37
Titel: Mit indy 9 eine .mp3 Datei senden (von server zu client)
Guten Abend alle zusammen!
Ich würde sehr sehr gerne eine Mp3 Datei von IDTCPSERVER zu IDTCPCLIENT senden. Nach Suche hier im Forum bin ich dabei auf folgendes Ergebnis gekommen:
(SERVER)

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.IdTCPServer1Execute(AThread: TIdPeerThread);

var
  FStream: TFileStream;
begin

  FStream := TFileStream.Create(opendialog1.filename, fmOpenRead);
  try
    AThread.Connection.OpenWriteBuffer;
    AThread.Connection.WriteStream(FStream);
    AThread.Connection.CloseWriteBuffer;
  finally
    AThread.Connection.Disconnect;
    FStream.Free;
  end;
  end;




procedure TForm1.Button1Click(Sender: TObject);
begin
opendialog1.Execute;
end;


Nun zum Client:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure TForm1.Button1Click(Sender: TObject);
var
  FStream: TFileStream;
begin
  FStream := TFileStream.Create('C:\test.wma', fmCreate);
  with Form1 do begin
    IdTCPClient1.Connect; // Verbindung aufbauen
    try
      IdTCPClient1.ReadStream(FStream, -1, True); // Stream empfangen
      FStream.Seek(0, soFromBeginning);
    finally  
      IdTCPClient1.Disconnect; // Verbindung schließen
      FStream.Free; // Stream freigeben  
    end;
  end;  
end


end.

So das Problem ist, dass ich zwar in C:\ eine Datei empfnge, die hat aber leider 0 Byte, da nach wenigen Sekunden eine Fehlermeldung des Clients kommt.
Ich bin ein absoluter Neuling in Sachen indy also bitte helft mir!!!^^
Vielen Vielen Dank!!
PigfaceJoe


Narses - Mo 30.10.06 00:43

Moin!

Das Grundproblem, du brauchst ein Protokoll. ;) Hier [http://www.delphi-library.de/topic_Warum+gibt+es+kein+ReceiveStream+bei+den+Sockets_65367.html] kannst du lesen, warum (geht zwar um die Sockets, aber das Problem ist das gleiche).

Das ist konkret die interessante Stelle:

Delphi-Quelltext
1:
IdTCPClient1.ReadStream(FStream, -1, True); // Stream empfangen                    

Damit das auch wirklich funktioniert, muss da die Länge des Streams hin.

cu
Narses


pigfacejoe - Mo 30.10.06 00:50

Vielen Dank für deine Antwort!!!
Nur wie erstelle ich so ein Protokoll bzw wie bekomme ich die Grösse der Datei und wo muss die dann im Quelltext hin?


Narses - Mo 30.10.06 01:17

Moin!

TFileStream hat die Eigenschaft .Size, das ist die Dateigröße. Die sendest du einfach vor dem Stream. Da .Size vom Typ Int64 ist (=8 Bytes), kannst du das relativ einfach handhaben. Und schon ist dein Protokoll fertig (Größe+Daten). ;)

cu
Narses


pigfacejoe - Mo 30.10.06 01:20

Soll ich das dann einfach so ändern?

Delphi-Quelltext
1:
IdTCPClient1.ReadStream(FStream, Filestream.size, True); // Stream empfangen                    

oder wie meintest du das mit vor dem Stream senden?


Narses - Mo 30.10.06 01:21

Moin!

Du hast doch beim Client die Größe noch gar nicht, und den FileStream willst du erst schreiben. ;) Du mußt beim Server zuerst die Streamgröße und dann erst den Stream selbst (die Daten) senden.

cu
Narses


pigfacejoe - Mo 30.10.06 01:27

Und wie sende ich die Grösse? einfach in ein memo rein und dann zum Client senden in ein memo un dann einlesen? oder wie? Ich weiss zwar wie du das meinst aber ich weiss nicht wie ich die Streamgrösse verschicke bzw wie ich das dann im Quelltext verwirklichen soll.


Narses - Mo 30.10.06 01:30

Moin!

Du könntest das so machen (nicht effizient, aber einfach): mach einen TMemoryStream auf, schreib die FileStreamgröße rein (mit Write) und kopiere dann die Streamdaten (mit CopyFrom). Dann sendest du den TMemoryStream.

cu
Narses


pigfacejoe - Mo 30.10.06 01:39

Kommt das dann ins ONExecute Ereignis vom Server rein?Und warum kann ich eigentlich nicht die Grösse mit inntostr in ein edit rein schreiben, das edit an meinen Clienten schicken , und dann dort bei
IdTCPClient1.ReadStream(FStream, strtoint(edit1.text), True);
einlesen ? Weil mit Streams kenne ich mich nicht so recht aus .
Also danke mal für geduld und Hilfe so spät in der Nacht!


Narses - Mo 30.10.06 01:44

Moin!

user profile iconpigfacejoe hat folgendes geschrieben:
Und warum kann ich eigentlich nicht die Grösse mit inntostr in ein edit rein schreiben, das edit an meinen Clienten schicken , und dann dort bei IdTCPClient1.ReadStream(FStream, strtoint(edit1.text), True);
einlesen ? Weil mit Streams kenne ich mich nicht so recht aus .

Klar geht das, ist noch ineffektiver als mein Vorschlag, aber wenn du das hinkriegst, dann probier´s doch erstmal so. ;) Besser machen kann man das immer noch. :D

cu
Narses


pigfacejoe - Di 31.10.06 17:03

Ist zwar inaktiv, hat aber geklappt. :lol: Vielen Dank!


elundril - Mi 27.06.07 10:42

sorry das ich das alte thema rauskram aber besser als ich mach ein neues auf oder?? ;-)

zu meiner Frage:
Funktioniert das nur übers internet??

lg elundril


Narses - Mi 27.06.07 11:05

Moin!

user profile iconelundril hat folgendes geschrieben:
Funktioniert das nur übers internet?

Wenn´s über´s Internet geht, dann geht´s doch wohl erst recht im LAN, hm? ;)

cu
Narses


elundril - Mi 27.06.07 14:55

und kann man irgendwie nur das netzwerk aktivieren?? also das man nur übers netzwerk senden kann??

lg elundril


Narses - Mi 27.06.07 15:24

Moin!

user profile iconelundril hat folgendes geschrieben:
und kann man irgendwie nur das netzwerk aktivieren?? also das man nur übers netzwerk senden kann??

:?!?:

Du redest wirr... :nixweiss:

cu
Narses


elundril - Do 28.06.07 13:28

du hast mir gesagt das man übers lan und übers internet senden kann. ich brauchs aber nur fürs lan und damit nicht aus versehen zu einer adresse im internet gesendet wird will ich irgendwie das internet ausschließen. geht das??

lg elundril


alias5000 - Do 28.06.07 13:34

Anhand der IP-Adresse [http://de.wikipedia.org/wiki/Private_IP-Adresse] sollte das einigermaßen möglich sein.
Ich bin mir da jetzt nicht sicher, aber das sollte an sich keine 100%ige Garantie dafür sein, dass nicht auch andere IP Adressen lokal sein können. Aber die verlinkten werden bevorzugt verwendet (Grund steht ja auch mit dabei).

Gruß
alias5000


elundril - Di 03.07.07 15:14

Mal eine paar andere fragen zu dem Thema.

1) Was passiert wenn ich einen Filestream mit meinem Programm zu einem anderen schicke der das programm nicht hat?

2) Was passiert wenn ich einen Filestream mit meinem Programm zu einem anderen schicke der mit meinem Programm den Stream NICHT verarbeitet?

lg elundril


Robinator - Di 03.07.07 16:02

user profile iconelundril hat folgendes geschrieben:
Mal eine paar andere fragen zu dem Thema.

1) Was passiert wenn ich einen Filestream mit meinem Programm zu einem anderen schicke der das programm nicht hat?

2) Was passiert wenn ich einen Filestream mit meinem Programm zu einem anderen schicke der mit meinem Programm den Stream NICHT verarbeitet?

lg elundril


user profile iconNarses hat folgendes geschrieben:
Moin!

:?!?:

Du redest wirr... :nixweiss:


alias5000 - Di 03.07.07 17:56

user profile iconelundril hat folgendes geschrieben:
Mal eine paar andere fragen zu dem Thema.

1) Was passiert wenn ich einen Filestream mit meinem Programm zu einem anderen schicke der das programm nicht hat?

2) Was passiert wenn ich einen Filestream mit meinem Programm zu einem anderen schicke der mit meinem Programm den Stream NICHT verarbeitet?

lg elundril


Dann passiert folgendes:
Indy wirft eine Exception. :idea:
Weil:
Wohin soll der TCPClient verbinden, wenn kein Server auf der Gegenseite lauscht?
Und wenn einer lauscht, kann er mit den Daten anstellen, was er will (dann gibts natürlich keine Exception)


elundril - Di 03.07.07 20:16

bis jetzt hab ichs noch nicht gefunden aber es kann sein das ich den wald vor lauter bäumen nicht sehe:

Kann man angeben auf welche IP er senden soll oder sendet Indy einfach an alle?

lg elundril


Narses - Di 03.07.07 20:31

Moin!

OMG... :?

user profile iconelundril hat folgendes geschrieben:
Kann man angeben auf welche IP er senden soll oder sendet Indy einfach an alle?

Wer ist denn "Indy"? Indiana Jones? Oder meinst du eine der Komponenten aus der Kompo-Sammlung... :roll: ;)

Faustregel:
TCP: verbindungsorientiert (Punkt-zu-Punkt-Verbindung)
UDP: verbindungslos (also auch "an alle" (in LAN!) möglich)

cu
Narses


elundril - Di 03.07.07 20:34

Und wie kann ich im IdTCP* die IP Adresse angeben?

lg elundril


Narses - Di 03.07.07 20:37

Moin!

user profile iconelundril hat folgendes geschrieben:
Und wie kann ich im IdTCP* die IP Adresse angeben?

Wenn du mal erklärst, was "die" IP-Adresse deiner Meinung nach ist? :nixweiss:

cu
Narses


elundril - Di 03.07.07 20:40

entweder eine 4 teilige Zahl à la 127.0.0.1 oder direkt der Computername à la "Mikes-Computer"

lg elundril


Narses - Di 03.07.07 20:42

Moin!

user profile iconelundril hat folgendes geschrieben:
entweder eine 4 teilige Zahl à la 127.0.0.1

OK, das ist eine IP(v4)-Adresse. ;)

user profile iconelundril hat folgendes geschrieben:
oder direkt der Computername à la "Mikes-Computer"

Und sowas nennt man einen Host-Namen, nicht IP-Adresse. Per DNS löst man sowas erst in eine IP-Adresse auf. :idea:

Hätten wir das also auch geklärt - worauf meine Frage aber nicht abzielte :P sondern: im Client oder im Server?

cu
Narses


elundril - Di 03.07.07 20:44

ich nehm an, da das file ja vom Server geschickt wird, im Server.

lg elundril


Narses - Di 03.07.07 20:46

Moin!

user profile iconelundril hat folgendes geschrieben:
ich nehm an, da das file ja vom Server geschickt wird,

TCP-Verbindungen sind voll-duplex, du kannst also vom Server aus sendern oder auch vom Client, sogar beides gleichzeitig. ;)

user profile iconelundril hat folgendes geschrieben:
im Server.

Im Server kann man keine IP-Adressen für Verbindungen angeben, dieser wartet immer nur auf Clientverbindungen - so gesehen hat der Server also immer die IP-Adresse(n) der Maschine, auf der der Dienst läuft.

Fazit: du gibst im Client eine Adresse an (IP oder Hostname), zu der eine Verbindung aufgebaut werden soll. :idea:

cu
Narses


elundril - Di 03.07.07 20:50

aber die Connection muss immer vom Server ausgehen oder?

lg elundril


Narses - Di 03.07.07 20:53

Moin!

user profile iconelundril hat folgendes geschrieben:
aber die Connection muss immer vom Server ausgehen oder?

Nein, genau anders rum. Schau dir mal diese Tutorials hier [http://www.delphi-library.de/topic_60744.html] an, ist zwar nicht Indy, aber es geht ja auch nur um das grundlegende Verständnis... :les: ;)

cu
Narses