最简RTSP客户端程序设计

转自https://blog.csdn.net/li_wen01/article/details/70260895
    为了更加清晰的了解RTSP协议,本文设计了一个最简的RTSP客户端程序,该程序向RTSP 依次发送OPTIONS, DESCRIBE, SETUP, PLAY , TEARDOWN请求,以查看服务端返回的数据。同时建立RTP和RTCP 通信,接收一包RTP和一包RTCP数据包。

说明:

服务端程序:live555 testProgs 中的 testH264VideoStreamer

服务端地址:192.168.0.6

多播地址    :232.231.110.2

RTP端口    :18888

RTCP端口 :18889

客户端地址:192.168.0.5

部分代码如下:

/*=============================================================================

FileName: rtspRequest.c

Desc: 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 1024

void 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 200 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("Connect 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;

}
    编译运行结果如下:

licaibiao@lcb:~/test/RTSP$ gcc rtspRequest.c -o test
licaibiao@lcb:~/test/RTSP$ ./test
socket created
address created
server connected
OPTION Reply Msg:
OPTIONS rtsp://192.168.0.6:8554/testStream RTSP/1.0
Cseq: 1
User-Agent: virtual client player

send successfully,total content is 99 bytes!
OPTION Reply Msg:
RTSP/1.0 200 OK
CSeq: 1
Date: Thu, Apr 20 2017 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: virtual client player

send successfully,total content is 125 bytes!
DESCRIBE Reply Msg:
RTSP/1.0 200 OK
CSeq: 2
Date: Thu, Apr 20 2017 07:27:32 GMT
Content-Base: rtsp://192.168.0.6:8554/testStream/
Content-Type: application/sdp
Content-Length: 589

v=0
o=- 1492673143011076 1 IN IP4 192.168.0.6
s=Session streamed 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 96
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 200 OK
CSeq: 3
Date: Thu, Apr 20 2017 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 200 OK
CSeq: 4
Date: Thu, Apr 20 2017 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 1024 Byte RTP message from server
Recv 48 byte 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 200 OK
CSeq: 5
Date: Thu, Apr 20 2017 07:27:33 GMT
Session: 75BF219C

-Agent: virtual client player

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 successfully,total content is 120 bytes!
teardown Reply Msg:
RTSP/1.0 200 OK
CSeq: 6
Date: Thu, Apr 20 2017 07:27:33 GMT

ession: 75BF219C
User-Agent: virtual client player

receive successfully,total content is 65bytes!
licaibiao@lcb:~/test/RTSP$

完整的工程代码下载路径:https://download.csdn.net/download/li_wen01/9820375

作者:li_wen01
来源:CSDN
原文:https://blog.csdn.net/li_wen01/article/details/70260895
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值