RTSP 消息拼装实例代码

整理了下之前文章提到的RTSP实例的代码,主要是拼装各类消息字段。

首先,抽取一个公共函数,用来根据消息类型,生成不同的format,供sprintf试用。

char * GetRTSPCmd( const char * szName)
{
	char *str = NULL;
	char const*  cmdFmt = NULL;
	if(!strcmp(szName, "OPTIONS"))
	{
		cmdFmt =
			"OPTIONS %s RTSP/1.0
"
			"CSeq: %d
"
			"%s"
			"%s"
#ifdef SUPPORT_REAL_RTSP
			REAL_OPTIONS_HEADERS
#endif
			"
";
	}
	else if(!strcmp(szName, "ANNOUNCE"))
	{
		cmdFmt =
			"ANNOUNCE %s RTSP/1.0
"
			"CSeq: %d
"
			"Content-Type: application/sdp
"
			"%s"
			"Content-length: %d

"
			"%s";
	}
	else if(!strcmp(szName, "PLAY"))
	{
		cmdFmt ="PLAY %s RTSP/1.0
"
			"CSeq: %d
"
			"Session: %s
"
			"%s"
			"%s"
			"%s"
			"%s"
			"
";

	}
	else if(!strcmp(szName, "PAUSE"))
	{
		cmdFmt =
			"PAUSE %s RTSP/1.0
"
			"CSeq: %d
"
			"Session: %s
"
			"%s"
			"%s"
			"
";
	}
	else if(!strcmp(szName, "RECORD"))
	{
		cmdFmt =
			"RECORD %s%s%s RTSP/1.0
"
			"CSeq: %d
"
			"Session: %s
"
			"Range: npt=0-
"
			"%s"
			"%s"
			"
";
	}
	else if(!strcmp(szName, "SET_PARAMETER"))
	{
		cmdFmt =
			"SET_PARAMETER %s RTSP/1.0
"
			"CSeq: %d
"
			"Session: %s
"
			"%s"
			"%s"
			"Content-length: %d

"
			"%s: %s
";
	}
	else if(!strcmp(szName, "GET_PARAMETER"))
	{
		cmdFmt =
			"GET_PARAMETER %s RTSP/1.0
"
			"CSeq: %d
"
			"Session: %s
"
			"%s"
			"%s"
			"Content-type: text/parameters
"
			"Content-length: %d

"
			"%s
";
	}
	else if(!strcmp(szName, "TEARDOWN"))
	{
		cmdFmt =
			"TEARDOWN %s RTSP/1.0
"
			"CSeq: %d
"
			"Session: %s
"
			"%s"
			"%s"
			"
";
	}
	else if(!strcmp(szName, "DESCRIBE"))
	{
		cmdFmt =
			"DESCRIBE %s RTSP/1.0
"
			"CSeq: %d
"
			"%s"
			"%s"
			"%s"
#ifdef SUPPORT_REAL_RTSP
			REAL_DESCRIBE_HEADERS
#endif
			"
";
	}
	else if(!strcmp(szName, "ANNOUNCE"))
	{
		cmdFmt =
			"ANNOUNCE %s RTSP/1.0
"
			"CSeq: %d
"
			"Content-Type: application/sdp
"
			"%s"
			"Content-length: %d

"
			"%s";
	}
	else if(!strcmp(szName, "SETUP"))
	{
		cmdFmt ="SETUP %s"
			"CSeq: %d
"
			"%s"
			"%s"
			"%s"
			"%s"
			"
";
	}
	str = (char*)cmdFmt;
	return str;
}


然后,针对每种消息类型,在做单独的拼装,下面主要介绍Client向Server发送的请求消息:

1.OPTION

#define  PP_NAME "User-Agent: rtsp client(v1.0)"
#define  PP_CRLF "
"
char * GetOptionCmd( char *url )
{
	int nlen, iret;
	char *ss;
	char *s = GetRTSPCmd("OPTIONS");

	nlen = strlen(s);
	iret = nlen + strlen(url) + strlen(PP_NAME) + 200;
	ss = (char*)malloc(iret);

	sprintf(ss, s, url, 1, PP_NAME, PP_CRLF);


	return ss;
}


2.DESCRIBE

char * GetDescribeCmd( char *url )
{
	int nlen, iret;
	char *ss;
	char *s = GetRTSPCmd("DESCRIBE");

	nlen = strlen(s);
	iret = nlen + strlen(url) + strlen(PP_NAME) + 200;
	ss = (char*)malloc(iret);

	sprintf(ss, s, url, 2, PP_NAME, PP_CRLF, PP_CRLF);

	return ss;
}


3.SETUP

char * GetSetupCmd( char *url , int port1, int port2)
{
	int nlen, iret;
	char *ss;
	char *s = GetRTSPCmd("SETUP");

	nlen = strlen(s);
	iret = nlen + strlen(url) + strlen(PP_NAME) + 200;
	ss = (char*)malloc(iret);
	char buf[128] = {0};
	char buf2[128] = {0};
	if(port1 == 0)
		strcpy(buf, "
Transport: RTP/AVP/TCP;unicast;interleaved=0-1");
	else
		sprintf(buf, "
Transport: RTP/AVP;unicast;client_port=%d-%d", ntohs(port2), ntohs(port1));
	sprintf(buf2, "%s/track1 RTSP/1.0
", url);
	sprintf(ss, s, buf2, 3,  PP_NAME, buf, PP_CRLF, PP_CRLF);

	return ss;
}


4.PLAY

char * GetPlayCmd( char *url , char *session, char *range)
{
	int nlen, iret;
	char *ss;
	char *s = GetRTSPCmd("PLAY");

	nlen = strlen(s);
	iret = nlen + strlen(url) + strlen(PP_NAME) + 200;
	ss = (char*)malloc(iret);

	//char buf[128] = {0};
	//sprintf(buf, "Session: %s
", session);

	sprintf(ss, s, url, 4, session, range, PP_NAME, PP_CRLF, PP_CRLF);

	return ss;
}


原文地址:https://www.cnblogs.com/dyllove98/p/3148351.html