TCP client does not receive responses from RTSP server

In Delphi XE2, I use the TTCPClient component to communicate with the RTSP server. After the trial version and the error did not receive a response from the server, I switched the project to send HTTP requests through port 80 (instead of 554 for RTSP) and tried to send a request to the site (www.google.com). I still do not get a response.

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

Server connection

 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 OnReceive never raised, nothing is returned from any server to which I connect.

What am I doing wrong here?

References

Here are some links to which I refer:

The camera I'm working with is Grandstream GXV3601LL

UPDATE

I came to the conclusion that the problem was with the RTSP server and asked a question in the forums on the Grandstream website. The code works with other server connections.

+6
source share
2 answers

This works for me, it depends if you are in lock 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 an RTSP server (in this case you are 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. 
+6
source

The reason the OnReceive event OnReceive not raised is because TTCPClient is NOT an asynchronous component, for example, you are trying to process it. The OnReceive event OnReceive NOT OnReceive just like the old TClientSocket.OnRead event. The OnReceive event OnReceive raised only inside the ReceiveBuf() method ( ReceiveLn() calls ReceiveBuf() internally). The data that is sent to the OnReceive event is the same data that the ReceiveBuf() method returns on output. You have a catch-22 situation - you are waiting for the OnReceive event before calling ReceiveLn() , but OnReceive will not be triggered until you call ReceiveLn() first. If you want to use TTCPClient asynchronously, you will have to periodically call its ReceiveLn() method either in the timer or in the OnReceive NOT inside the OnReceive event.

The TTCPClient component is part of the old CLX environment for Kylix. It is not part of VCL or even FireMonkey and should no longer be used. Use either the old TClientSocket component (which is deprecated but still available), or replace it with another component library, such as Indy.

+2
source

Source: https://habr.com/ru/post/927693/


All Articles