Search code examples
delphisocketsdelphi-xe2rtsptcp

TCP Client not receiving responses back from RTSP server


In Delphi XE2, I'm using the TTCPClient component to communicate with an RTSP server. After trial and error not getting a response back from the server, I switched the project to send HTTP requests via port 80 (instead of 554 for RTSP) and tried to send a request to a website (www.google.com specifically). I'm still not getting any response.

I have a TTCPClient component on the main form (Form1) called Client, a TMemo control called Log, a TEdit control called txtHost, and a TBitBtn control. Here's the relevant parts of the code:

Connecting to Server

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  if Client.Active then Client.Disconnect;
  Client.RemoteHost:= txtHost.Text;
  Client.RemotePort:= '80'; // '554';
  Client.Connect;
end;

OnConnect Event Handler (HTTP)

procedure TForm1.ClientConnect(Sender: TObject);
var
  S: String;
begin
  Client.Sendln('GET / HTTP/1.0');
  Client.SendLn('');
end;

OnConnect Event Handler (RTSP)

procedure TForm1.ClientConnect(Sender: TObject);
var
  S: String;
begin
  Client.SendLn('OPTIONS * RTSP/1.0');
  Client.SendLn('CSeq:0');
  Client.SendLn('');
end;

OnReceive Event Handler

procedure TForm1.ClientReceive(Sender: TObject; Buf: PAnsiChar;
  var DataLen: Integer);
var
  S, R: String;
begin
  S:= Client.Receiveln;
  while S <> '' do begin
    R:= R+ S;
    S:= Client.Receiveln;
  end;
  Log.Lines.Append('> RECEIVED ' + R);
end;

OnError Event Handler

procedure TForm1.ClientError(Sender: TObject; SocketError: Integer);
begin
  Log.Lines.Append('> ERROR '+IntToStr(SocketError));
end;

The OnReceive event is never called, nothing is coming back from any Server I'm connecting to.

What am I doing wrong here?

References

These are some links which I'm referencing to:

The camera I'm working with is Grandstream GXV3601LL

UPDATE

I've concluded that the issue is with the RTSP server, and have asked a question on the forums on Grandstream's website. The code does work with other server connections.


Solution

  • This works for me, it depends if you are in blocking mode or not:

    unit Unit11;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Sockets, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, StdCtrls;
    
    type
      TForm1 = class(TForm)
        IdTCPClient1: TIdTCPClient;
        TcpClient1: TTcpClient;
        Memo1: TMemo;
        procedure TcpClient1Connect(Sender: TObject);
        procedure TcpClient1Receive(Sender: TObject; Buf: PAnsiChar; var DataLen: Integer);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
     TcpClient1.BlockMode := bmBlocking;
     TcpClient1.RemoteHost := 'www.google.com';
     TcpClient1.RemotePort := '80';
     TcpClient1.Connect;
    end;
    
    procedure TForm1.TcpClient1Connect(Sender: TObject);
    
    var s : string;
    
    begin
     memo1.Lines.Add('connected');
     TcpClient1.Sendln('GET /');
     s := TcpClient1.Receiveln;
     memo1.Lines.Add(S);
    end;
    
    end.
    

    EDIT

    here is a real world example with a RTSP server (youtube in this case) I used Indy IdTcpClient

    unit Unit11;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Sockets, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, StdCtrls;
    
    type
      TForm1 = class(TForm)
        Memo1: TMemo;
        Client: TIdTCPClient;
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.FormCreate(Sender: TObject);
    
    var s : string;
    
    begin
     Client.Host := 'v5.cache6.c.youtube.com';
     Client.Port := 554;
     Client.Connect;
     Client.IOHandler.Writeln('OPTIONS * RTSP/1.0');
     Client.IOHandler.Writeln('CSeq: 1');
     Client.IOHandler.Writeln('');
    
     s := Client.IOHandler.ReadLn;
     Memo1.Lines.Add(s);
     s := Client.IOHandler.ReadLn;
     Memo1.Lines.Add(s);
    end;
    
    end.