Autor Beitrag
Christian R.
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 03.12.07 05:12 
Bei meiner Arbeit an meinem Download-Tool bin ich inzwischen ein ganzes Stück weitergekommen. Heute habe ich einen Stream, der durch das MMS-Protokoll behandelt wird, ins Ziel genommen.

Aufgrund der Infos von :arrow: WikiPedia :: MMS-Protokoll - Erzeugung einer MMS-Sitzung habe ich einen Indy-TCP-Client gestartet. Dieser enthält meinen gewählten Port für die UDP-Verbindung, den ich in einen nebenbei gestarteten Indy-UDP-Client eingetragen habe. Die Verbindung zum Server wurde erfolgreich hergestellt. Allerdings kann ich nur direkt vom eingetragenen Host streamen, was mir 0 Byte einbringt, aber wenigstens keinen Fehler. Die Adresse, auf die es mir ankommt ist wie folgende aufgebaut:

ausblenden Quelltext
1:
mms://wms.domain.fm/audiofile.wma					

Ich weiß nicht, wie ich die angegebene URL streamen kann. Wo trage ich sie ein?

Es wäre sehr nett, wenn mir bitte jemand bei diesem Problem helfen könnte. Nach den Ausführungen von Wikipedia erscheint mir alles richtig, aber ich würde gern wissen ob ich es auch wirklich richtig angestellt habe. Wenn Ihr noch Informationen braucht, fragt bitte. Ich weiß nicht, welche für Euch relevant sind.

Danke, Christian
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Mo 03.12.07 10:03 
Bei MMS baut der Client eine TCP-Verbindung auf Port 1755 auf. Dann wird über ein bestimmtes Protokoll ein UDP-Port ausgehandelt, da musst Du Dir die Protokollspezifikationen genau anschauen. Der Server teilt Dir dann nach einer Anfrage von Dir(!) den UDP-Port mit.

Dann kannst Du Deinen UDP-Listener auf diesen Port konfigurieren und der Server wird sich dann über diesen Port mit Dir verbinden. Du musst dabei aber darauf achten, dass Du vom Internet über diesen Port erreichbar bist (Firewall!).

So steht es jedenfalls in dem Wikipedia-Artikel drin, aber ich glaube, Dein Verständnis davon geht etwas in die falsche Richtung, sonst würde es ja funktionieren ;)

Zeig am Besten mal ein wenig Code, wie Du die beiden Id-Komponenten erstellst.
Christian R.
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 03.12.07 11:56 
Tach.

Den Port 1755 spreche ich beim Verbindungsaufbau an. Da ich einen UDP-Port meiner Wahl übermitteln soll, habe ich es erst mal mit BoundPort versucht. Aber ich glaube, ;) das geht so in die Hose. Ich gehe inzwischen davon aus, dass dem Server einen Header senden muss, durch dem ich dem Server mitteile, was ich von ihm will. Und die Antwort muss ich sicher mit "TIdTCPClient.StreamBuffer( )" in Empfang nehmen.

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:
procedure TFormTriggerLoad.IndTCPClientConnected
          ( Sender : TObject );
begin
  ShowMessage( 'TCPClient connected.' );
end;

procedure TFormTriggerLoad.IndTCPClientDisconnected
          ( Sender : TObject );
begin
  ShowMessage( 'TCPClient disconnected.' );
end;

procedure TFormTriggerLoad.BttDLTCPConnectClick
          ( Sender : TObject );
begin
  if IndTCPClient.Connected = False then
  begin
    Self.IndUDPClient.Host      := Self.ExtractHostFromURL( Self.EdtDLURL );   // Ich glaube, das funktioniert
    Self.IndUDPClient.Port      := 24050;                                      // so nicht.
    Self.IndTCPClient.BoundIP   := cNul;     // !! Weiß ehrlich gesagt nicht, wie ich die herausfinde.
    Self.IndTCPClient.BoundPort := 24050;    // Ich bin davon ausgegangen, dass ich hier meinen UDP eintrage
                                             // Wiki: "... um seine IP-Adresse und einen selbst gewählten UDP-Port zu übermitteln."
                                             // Inzwischen weiß ich, dass hier allgemein nur der Port für den Empfang via TCP eingetragen wird.
    Self.IndTCPClient.Host      := Self.ExtractHostFromURL( Self.EdtDLURL );
    Self.IndTCPClient.Port      := 1755;
    Self.IndTCPClient.Connect( 60 );
  end;
end;

procedure TFormTriggerLoad.BttDLTCPDisconnectClick
          ( Sender : TObject );
begin
  Self.IndTCPClient.Disconnect(  );
end;

procedure TFormTriggerLoad.BttDLStreamClick
          ( Sender : TObject );
var
  StreamTarget : TFileStream;
begin
  StreamTarget := TFileStream.Create( Self.DlgSaveDL.Text, fmCreate );
  Self.IndTCPClient.ReadStream( StreamTarget, -1, True );
  StreamTarget.Free(  );
end;


Mein Versuch, mittels des UDP-Clients mit dem Server zu kommunizieren kann so nicht funktionieren. Da bin ichmir auch sicher.

Ich weiß immer noch nicht, wo ich die komplette URL eintrage, also wird sie sicher auch an den Server als Anfrage gesendet.

Sind die Informationen ausreichend?

//Edit: Ich bin gerade damit beschäftigt, herauszufinden, wie die Anfragen via TCP aussehen müssen. Wie kann ich diese dann mit der Indy-Kompo senden?
Christian R.
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 04.12.07 03:47 
Ich habe inzwischen einiges mehr zum Thema gelesen. Anstelle eines UDPClients verwende ich nun einen Server.
Hier meine Routinen, wie sie derzeit aussehen.

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:
{
type
  IndUDPServer = TIdUDPServer;
  IndTCPClient = TIdTCPClient;
}

procedure TFormTriggerLoad.BttDLUDPStreamClick
          ( Sender : TObject );
begin
  if IndTCPClient.Connected = False then
  begin
    Self.IndTCPClient.Host := Self.ExtractHost( Self.EdtDLURL.Text );
    Self.IndTCPClient.Port := 1755;
    Self.TCPInfoString     := 'Host: ' + Self.IndTCPClient.Host + #10 + 'Port: ' + IntToStr( Self.IndTCPClient.Port );
    Self.IndTCPClient.Connect( -1 );
    if Self.IndTCPClient.Connected = True then
    begin
      // Hier müsste ich nun die Server-Anfragen senden. Aber wie sehen diese aus und wie werden sie gesendet?
      Self.IndTCPClient.Disconnect(  );
    end
    else
      ShowMessage( 'TCP-Connection failed:' + #10#10 + Self.TCPInfoString );
  end
  else
      ShowMessage( 'TCP already connected:' + #10#10 + 'Host: ' + Self.TCPInfoString );
end;

procedure TFormTriggerLoad.IndUDPServerUDPRead
          ( Sender : TObject; AData : TStream; ABinding : TIdSocketHandle );
var
  StreamTarget : TFileStream;
  Buffer       : Array0..4096 ] of Byte;
  BufferRead   : Longint;
begin
  StreamTarget := TFileStream.Create( Self.EdtDLPathTarget.Text, fmCreate );
  repeat
    BufferRead := AData.Read( Buffer, SizeOf( Buffer ) );
  until ( BufferRead = 0 ) or ( StreamTarget.Write( Buffer, BufferRead ) = 0 );
  StreamTarget.Free(  );
end;

Quelle: Brauche Crashcurs in UDP

(Das noch Fehlernehandlungen geschrieben werden müssen ist klar. Ich möchte aber erst einmal eine Verbindung herstellen.)

Das Prinzip des UDP habe ich jetzt soweit verstanden. Der Stream wird vom Host im Netz über einen definierten Port gesendet. Über diesen Port kann mein UDP-Server die Daten lesen. Ohne Anmeldung, etc.. Allerdings muss für das Streamen mittels MME-Protokoll dieser Port vom Host geholt werden. Wurde er empfangen, kann die TCP-Verbindung wieder geschlossen werden. Bei einem Chat-Programm vie UDP beispielsweise fällt die TCP-Verbindung komplett weg, da man sich von vornherein über einen festen Port einigen kann, welcher standardmäßig für die auszutauschenden UDP-Streams verwendet wird.

Der UDP-Server bekommt den UDP-Port aus der Anfrage des TCP-Clients an den Host zugewiesen, welchen er quasi die ganze Zeit abhört, und sobald ein Datenpaket kommt, dieses auch annimmt (onUDPRead).

Nun weiß ich nicht, wie ich eine Anfrage an den Host im Netz sende, damit er mir einen UDP-Port zurückgibt, welchen ich für den Stream nutzen kann. Ich weiß auch nicht, wie ich dem Server mitteile, welchen Stream er mir via UDP senden soll. Wie benutze ich in diesem Fall den TCPClient?

Wenn ich etwas von der Theorie bis hierher falsch verstanden habe, korrigiert mich bitte.

//Edit @user profile iconUGrohne: Deinen Hinweis zum Aushandeln des UDP Port über ein weiteres Protokoll habe ich gelesen. Aber dazu weiß ich leider nicht wie.
Christian R.
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 04.12.07 22:52 
Ich möchte gern von den Experten wissen: Was hindert Euch daran, diese Frage zu beantworten? Ich habe einige einschlägige Beiträge zum Thema hier und in anderen Foren gelesen. So auch einige Beiträge, die darauf schließen lassen, dass Ihr mir die Antwort geben könntet. Namen nenne ich jetzt keine. ;)

Egal ob es um ethische Gründe geht, wie z. B. krass formuliert "Wir wissen nicht, was Du damit anstellen willst und wollen das Risiko nicht eingehen jemanden bei rechtlich bedenklichen Aktivitäten zu unterstützen" oder einfach nur der Grund "Finde es doch selbst heraus, dieses Wissen wollen wir nicht einfach jedem preisgeben", so sollte es kein Problem sein, dies hier als Antwort zu schreiben. Aber einfach jemandem anfänglich helfen zu wollen (und auch das Wissen dazu zu haben) ;) um ihn dann trozdem auf der Frage sitzen lassen ist nicht die feine englische Art.

Think about it ... Es interessiert mich ernsthaft, warum mir die Hilfe sehr offensichtlich verweigert wird. Mit ehrlicher Kritik kann ich sehr gut umgehen. Aber eine solche Haltung verstehe ich nicht.


Christian

P.S.: Dieses Topic ist kein Offtopic. Ich wollte nur meine Meinung zu diesem Thema geschrieben haben und wer das Bedürfnis hat, sich zum Thema zu äußern, kann das hier gerne machen. Alles andere könnt ihr gern in einem dementsprechenden Thread unterbringen.
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Mi 05.12.07 14:10 
Du irrst Dich ein wenig. Es gibt hier offensichtlich keinen, der Dir diese Frage beantworten kann bzw. er hat dieses Topic nicht gelesen. Ich zitiere hier einfach mal wieder aus Wikipedia:
Wikipedia hat folgendes geschrieben:
[...]daher wird die genaue Spezifikation des MMS-Protokolls auch von Microsoft geheim gehalten.[...]

Das bedeutet, dass Du es leider selbst herausfinden musst bzw. Dir anschauen musst, wie die dort verlinkten Tools es machen, damit Du dieses nachbauen kannst.

Mehr kann ich dir dazu leider nicht sagen.