In order to understand the RTSP protocol more clearly, this paper designs a simplest RTSP client program, which sends the options, DESCRIBE, Setup, PLAY, teardown requests to rtsp in turn to view the data returned by the server. Both RTP and RTCP communication are established, and a packet of RTP and a packet of RTCP packets are received.
Description
Server-side program: live555 testprogs in Testh264videostreamer
Server address: 192.168.0.6
Multicast address: 232.231.110.2
RTP Port: 18888
RTCP Port: 18889
Client Address: 192.168.0.5
Some of the code is as follows:
/*============================================================================= # filename:rtsprequest.c # D Esc:client Connect to RTSP server # Author:licaibiao # lastchange:2017-04-19 =============================== ==============================================*/#include <stdio.h> #include <stdlib.h> #include < errno.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <sys/socket.h> # Include <resolv.h> #include <stdlib.h> #include <netinet/in.h> #include <arpa/inet.h> #include
<unistd.h> #include <fcntl.h> #define MAXBUF handel_option (char *inbuffer);
void Handel_describe (char *inbuffer, int sockfd);
void Handel_setup (char *inbuffer, int sockfd);
void Handel_play (char *inbuffer, int sockfd,char *sessionid);
void Handle_pause (char *inbuffer,int sockfd, char *sessionid);
void Handel_teardown (char *inbuffer, int sockfd,char *sessionid); int IntsearcH (char * buf, char * searchstr, int len);
int Strsearch (char * buf, char * searchstr, int len,char *dest);
int init_udpsocket (int port, struct sockaddr_in *servaddr, char *mcast_addr);
void Release_udpsocket (int socket_fd, char *mcast_addr);
void Proc_udpsocket (int socket_fd, struct sockaddr_in servaddr,int flag);
Char sendoptrequststr[] = "OPTIONS rtsp://192.168.0.6:8554/teststream rtsp/1.0\r\n";
Char useragentstr[] = "virtual client player\r\n";
Char successfullyreplystr[] = "rtsp/1.0 ok\r\n";
Char senddesrequststr[] = "DESCRIBE rtsp://192.168.0.6:8554/teststream rtsp/1.0\r\n";
Char sendsetuprequststr[] = "SETUP rtsp://192.168.0.6:8554/teststream/track1 rtsp/1.0\r\n";
Char sendplayrequststr[] = "PLAY rtsp://192.168.0.6:8554/teststream/rtsp/1.0\r\n";
Char sendteardownrequeststr[]= "TEARDOWN rtsp://192.168.0.6:8554/teststream/rtsp/1.0\r\n";
Char sendpauserequeststr[]= "PAUSE rtsp://192.168.0.6:8554/teststream/rtsp/1.0\r\n";
Char cseqheadstr[] = "CSEQ:"; Char UserheadStr[] = "user-agent:";
Char applicationheadstr[] = "Accept:";
Char transportheadstr[] = "Transport:";
Char sessionheadstr[] = "Session:";
Char rangeheadstr[] = "Range:";
int cseqcount=0;
int main (int argc, char **argv) {int sockfd,rtpsockfd,rtcpsockfd, Len;
struct sockaddr_in dest;
struct sockaddr_in rtpaddr;
struct sockaddr_in rtcpaddr;
Char serverip[]= "192.168.0.6";
Char mcast_addr[] = "232.231.110.2";
Char buffer[maxbuf + 1] = {0};
int serverport=8554;
int udpport=0;
cseqcount=0;
/* creat socket for RTSP */if ((SOCKFD = socket (af_inet, sock_stream, 0)) < 0) {perror ("socket");
Exit (errno);
} printf ("Socket created\n");
/* Init server Add and Port */bzero (&dest, sizeof (dest));
dest.sin_family = af_inet;
Dest.sin_port = htons (ServerPort); if (Inet_pton (Af_inet, ServerIP, &dest.sin_addr) < 0) {perror (serveriP);
Exit (errno);
} printf ("Address created\n"); /* Connect to Server */if (connect (SOCKFD, struct sockaddr *) &dest, sizeof (dest))! = 0) {perror ("Conne
CT error\n ");
Exit (errno);
} printf ("Server connected\n");
/* MAXBUF use to receive message from Stream server */bzero (buffer, maxbuf + 1);
/* Send message to Server */handel_option (buffer);
Len = Send (sockfd, buffer, strlen (buffer), 0); if (Len < 0) printf ("OPTION Reply msg:\n%s send error!
Error code is%d, error content is%s \ n ", buffer, errno, strerror (errno));
else printf ("OPTION Reply msg:\n%s Send successfully,total content is%d bytes!\n", buffer, Len);
Bzero (buffer, maxbuf + 1); /* Receive Message from server */len = recv (sockfd, buffer, maxbuf, 0); /* Option Reply */if (Len < 0) {printf ("option Reply msg:\n%s receive error! Error code is%d, error content is%s \ n ", buffer, errno, strerror (errno));
} else{printf ("OPTION Reply msg:\n%s receive successfully,total content is%dbytes!\n", buffer, Len);
} if (memcmp (buffer, successfullyreplystr, sizeof (SUCCESSFULLYREPLYSTR)-1) = = 0) {handel_describe (buffer, SOCKFD);
} else{printf ("The OPTION answer Msg is wrong!\n");
return 0;
} bzero (buffer, maxbuf + 1);
/* DESCRIBE Reply */len = recv (sockfd, buffer, maxbuf, 0); if (Len < 0) {printf ("DESCRIBE Reply msg:\n%s receive error!
Error code is%d, error content is%s \ n ", buffer, errno, strerror (errno));
} else{printf ("DESCRIBE Reply msg:\n%s receive successfully,total content is%dbytes!\n", buffer, Len);
} if (memcmp (buffer, successfullyreplystr, sizeof (SUCCESSFULLYREPLYSTR)-1) = = 0) {handel_setup (buffer, SOCKFD);
} else{printf ("The DESCRIBE answer Msg is wrong!\n");
return 0;
} bzero (buffer, maxbuf + 1);
Len = recv (sockfd, buffer, maxbuf, 0); if (Len < 0) {printf ("SEtup Reply msg:\n%s receive error!
Error code is%d, error content is%s \ n ", buffer, errno, strerror (errno));
} else{printf ("SETUP Reply msg:\n%s receive successfully,total content is%dbytes!\n", buffer, Len);
} Char sessionidtmp[30];
Bzero (sessionidtmp,sizeof (sessionidtmp));
Strsearch (Buffer, "Session:", 9, sessionidtmp);
if (memcmp (buffer, successfullyreplystr, sizeof (SUCCESSFULLYREPLYSTR)-1) = = 0) {char searchstrtmp[13]= "port=";
Udpport=intsearch (buffer,searchstrtmp,5);
if (udpport==0) {return 0;
} printf ("The UDP port is%d\n", udpport);
Bzero (&rtpaddr,sizeof (RTPADDR));
Bzero (&rtcpaddr,sizeof (RTCPADDR));
RTPSOCKFD = Init_udpsocket (Udpport, &rtpaddr, mcast_addr);
RTCPSOCKFD = Init_udpsocket (udpport+1, &rtcpaddr, mcast_addr);
Handel_play (buffer, sockfd,sessionidtmp);
} else {printf ("The SETUP answer Msg is wrong!\n");
return 0;
} bzero (buffer, maxbuf + 1);
Len = recv (sockfd, buffer, maxbuf, 0); if (Len < 0) {printf ("PLAY Reply msg:\n%s receive error!
Error code is%d, error content is%s \ n ", buffer, errno, strerror (errno));
}else{printf ("PLAY Reply msg:\n%s receive successfully,total content is%dbytes!\n", buffer, Len); } if (memcmp (buffer, successfullyreplystr, sizeof (SUCCESSFULLYREPLYSTR)-1)! = 0) {printf ("The play Answer MSG
is wrong!\n ");
return 0;
} bzero (buffer, maxbuf + 1);
printf ("Now,receiving RTP packets data......\n");
Proc_udpsocket (RTPSOCKFD, rtpaddr, 0);
Proc_udpsocket (RTCPSOCKFD, rtcpaddr, 1);
Handle_pause (buffer, SOCKFD, sessionidtmp);
Len = recv (sockfd, buffer, maxbuf, 0); if (Len < 0) {printf ("PAUSE Reply msg:\n%s receive error!
Error code is%d, error content is%s \ n ", buffer, errno, strerror (errno));
} else{printf ("PAUSE Reply msg:\n%s receive successfully,total content is%dbytes!\n", buffer, Len); } if (memcmp (buffer, successfullyreplystr, sizeof (SUCCESSFULLYREPLYSTR)-1)! = 0{printf ("The pause answer Msg is wrong!\n");
return 0;
} bzero (buffer, maxbuf + 1);
Handel_teardown (buffer, sockfd,sessionidtmp);
Len = recv (sockfd, buffer, maxbuf, 0); if (Len < 0) {printf ("Teardown Reply msg:\n%s receive error!
Error code is%d, error content is%s \ n ", buffer, errno, strerror (errno));
} else{printf ("Teardown Reply msg:\n%s receive successfully,total content is%dbytes!\n", buffer, Len);
} release_udpsocket (RTPSOCKFD, mcast_addr);
Release_udpsocket (RTCPSOCKFD, mcast_addr);
return 0; }
The results of the compilation run are as follows:
licaibiao@lcb:~/test/rtsp$ gcc rtsprequest.c-o test licaibiao@lcb:~/test/rtsp$./test socket created address created Ser ver connected OPTION Reply msg:options rtsp://192.168.0.6:8554/teststream rtsp/1.0 cseq:1 user-agent:virtual Client Pl
Ayer Send successfully,total content is bytes! OPTION Reply msg:rtsp/1.0-OK cseq:1 date:thu, Apr 07:27:32 GMT public:options, DESCRIBE, SETUP, TEARDOWN,
PLAY, PAUSE, Get_parameter, set_parameter receive successfully,total content is 152bytes! DESCRIBE Request msg:describe rtsp://192.168.0.6:8554/teststream rtsp/1.0 cseq:2 ACCEPT:APPLICATION/SDP user-agent:vi
Rtual client player Send successfully,total content is bytes! DESCRIBE Reply msg:rtsp/1.0 OK cseq:2 date:thu, Apr 07:27:32 GMT content-base:rtsp://192.168.0.6:8554/tes TSTREAM/CONTENT-TYPE:APPLICATION/SDP content-length:589 v=0 o=-1492673143011076 1 in IP4 192.168.0.6 s=Session stream Ed by "Testh264videostreamer" i=test.264 t=0 0 a=tool:lIVE555 streaming Media v2017.04.10 a=type:broadcast a=control:* a=source-filter:incl in IP4 * 192.168.0.6 a=rtcp-unicast: Reflection A=range:npt=0-a=x-qt-text-nam:session streamed by "Testh264videostreamer" a=x-qt-text-inf:test.264 m= Video 18888 RTP/AVP c=in IP4 232.231.110.2/255 b=as:500 a=rtpmap:96 h264/90000 a=fmtp:96 packetization-mode=1;profile- level-id=640015;sprop-parameter-sets=z2qafazzqecmweqaaambkaaal2g8wlzy,aovssiw= A=control:track1 Receive
Successfully,total content is 757bytes! SETUP Request msg:setup rtsp://192.168.0.6:8554/teststream/track1 rtsp/1.0 cseq:3 Transport:rtp/avp;unicast;client_
port=31126-31127 user-agent:virtual client Player send successfully,total content is 156 bytes! SETUP Reply msg:rtsp/1.0-OK cseq:3 date:thu, Apr 07:27:32 GMT transport:rtp/avp;multicast;destination=232 .231.110.2;source=192.168.0.6;port=18888-18889;ttl=255 session:75bf219c;timeout=65 Receive Successfully,total
Content is 195bytes! The UDP port is 18888 PLAY Request msg:play rtsp://192.168.0.6:8554/teststream/rtsp/1.0 cseq:4 session:75bf219c range:npt=0.000-user-agent:
Virtual client player Send Successfully,total content is 135 bytes! PLAY Reply msg:rtsp/1.0 cseq:4 date:thu, Apr 07:27:32 GMT range:npt=0.000-session:75bf219c rtp-info: url=rtsp://192.168.0.6:8554/teststream/track1;seq=53244;rtptime=3158552668 Receive Successfully,total content is
189bytes!
Now,receiving RTP Packets Data ... RECV 1024x768 byte RTP message from server Recv bytes RTCP message from Server,they are:o t F e Q (f o t u B u n T u PAUSE Request msg:pause rtsp://192.168.0.6:8554/teststream/rtsp/1.0 cseq:5 session:75bf219c user-agent
: Virtual client player send Successfully,total content is 117 bytes! PAUSE Reply msg:rtsp/1.0 $ OK cseq:5 date:thu, APR 07:27:33 GMT session:75bf219c-agent:virtual Client Pl
Ayer receive Successfully,total content is 84bytes! TEARDOWN Request Msg:teardowN rtsp://192.168.0.6:8554/teststream/rtsp/1.0 cseq:6 session:75bf219c user-agent:virtual client player Send SUCCESSF
Ully,total content is bytes! Teardown Reply msg:rtsp/1.0 OK cseq:6 date:thu, Apr 07:27:33 GMT ession:75bf219c user-agent:virtual CLI
ENT player receive successfully,total content is 65bytes! licaibiao@lcb:~/test/rtsp$
Complete Engineering Code Download path: Simplest RTSP client program design