整理了下之前文章提到的RTSP實例的代碼,主要是拼裝各類消息字段。
首先,抽取一個公共函數,用來根據消息類型,生成不同的format,供sprintf試用。
[cpp]
char * GetRTSPCmd( const char * szName)
{
char *str = NULL;
char const* cmdFmt = NULL;
if(!strcmp(szName, "OPTIONS"))
{
cmdFmt =
"OPTIONS %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"%s"
"%s"
#ifdef SUPPORT_REAL_RTSP
REAL_OPTIONS_HEADERS
#endif
"\r\n";
}
else if(!strcmp(szName, "ANNOUNCE"))
{
cmdFmt =
"ANNOUNCE %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"Content-Type: application/sdp\r\n"
"%s"
"Content-length: %d\r\n\r\n"
"%s";
}
else if(!strcmp(szName, "PLAY"))
{
cmdFmt ="PLAY %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"Session: %s\r\n"
"%s"
"%s"
"%s"
"%s"
"\r\n";
}
else if(!strcmp(szName, "PAUSE"))
{
cmdFmt =
"PAUSE %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"Session: %s\r\n"
"%s"
"%s"
"\r\n";
}
else if(!strcmp(szName, "RECORD"))
{
cmdFmt =
"RECORD %s%s%s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"Session: %s\r\n"
"Range: npt=0-\r\n"
"%s"
"%s"
"\r\n";
}
else if(!strcmp(szName, "SET_PARAMETER"))
{
cmdFmt =
"SET_PARAMETER %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"Session: %s\r\n"
"%s"
"%s"
"Content-length: %d\r\n\r\n"
"%s: %s\r\n";
}
else if(!strcmp(szName, "GET_PARAMETER"))
{
cmdFmt =
"GET_PARAMETER %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"Session: %s\r\n"
"%s"
"%s"
"Content-type: text/parameters\r\n"
"Content-length: %d\r\n\r\n"
"%s\r\n";
}
else if(!strcmp(szName, "TEARDOWN"))
{
cmdFmt =
"TEARDOWN %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"Session: %s\r\n"
"%s"
"%s"
"\r\n";
}
else if(!strcmp(szName, "DESCRIBE"))
{
cmdFmt =
"DESCRIBE %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"%s"
"%s"
"%s"
#ifdef SUPPORT_REAL_RTSP
REAL_DESCRIBE_HEADERS
#endif
"\r\n";
}
else if(!strcmp(szName, "ANNOUNCE"))
{
cmdFmt =
"ANNOUNCE %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"Content-Type: application/sdp\r\n"
"%s"
"Content-length: %d\r\n\r\n"
"%s";
}
else if(!strcmp(szName, "SETUP"))
{
cmdFmt ="SETUP %s"
"CSeq: %d\r\n"
"%s"
"%s"
"%s"
"%s"
"\r\n";
}
str = (char*)cmdFmt;
return str;
}
char * GetRTSPCmd( const char * szName)
{
char *str = NULL;
char const* cmdFmt = NULL;
if(!strcmp(szName, "OPTIONS"))
{
cmdFmt =
"OPTIONS %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"%s"
"%s"
#ifdef SUPPORT_REAL_RTSP
REAL_OPTIONS_HEADERS
#endif
"\r\n";
}
else if(!strcmp(szName, "ANNOUNCE"))
{
cmdFmt =
"ANNOUNCE %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"Content-Type: application/sdp\r\n"
"%s"
"Content-length: %d\r\n\r\n"
"%s";
}
else if(!strcmp(szName, "PLAY"))
{
cmdFmt ="PLAY %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"Session: %s\r\n"
"%s"
"%s"
"%s"
"%s"
"\r\n";
}
else if(!strcmp(szName, "PAUSE"))
{
cmdFmt =
"PAUSE %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"Session: %s\r\n"
"%s"
"%s"
"\r\n";
}
else if(!strcmp(szName, "RECORD"))
{
cmdFmt =
"RECORD %s%s%s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"Session: %s\r\n"
"Range: npt=0-\r\n"
"%s"
"%s"
"\r\n";
}
else if(!strcmp(szName, "SET_PARAMETER"))
{
cmdFmt =
"SET_PARAMETER %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"Session: %s\r\n"
"%s"
"%s"
"Content-length: %d\r\n\r\n"
"%s: %s\r\n";
}
else if(!strcmp(szName, "GET_PARAMETER"))
{
cmdFmt =
"GET_PARAMETER %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"Session: %s\r\n"
"%s"
"%s"
"Content-type: text/parameters\r\n"
"Content-length: %d\r\n\r\n"
"%s\r\n";
}
else if(!strcmp(szName, "TEARDOWN"))
{
cmdFmt =
"TEARDOWN %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"Session: %s\r\n"
"%s"
"%s"
"\r\n";
}
else if(!strcmp(szName, "DESCRIBE"))
{
cmdFmt =
"DESCRIBE %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"%s"
"%s"
"%s"
#ifdef SUPPORT_REAL_RTSP
REAL_DESCRIBE_HEADERS
#endif
"\r\n";
}
else if(!strcmp(szName, "ANNOUNCE"))
{
cmdFmt =
"ANNOUNCE %s RTSP/1.0\r\n"
"CSeq: %d\r\n"
"Content-Type: application/sdp\r\n"
"%s"
"Content-length: %d\r\n\r\n"
"%s";
}
else if(!strcmp(szName, "SETUP"))
{
cmdFmt ="SETUP %s"
"CSeq: %d\r\n"
"%s"
"%s"
"%s"
"%s"
"\r\n";
}
str = (char*)cmdFmt;
return str;
}
然後,針對每種消息類型,在做單獨的拼裝,下面主要介紹Client向Server發送的請求消息:
1.OPTION
[cpp]
#define PP_NAME "User-Agent: rtsp client(v1.0)"
#define PP_CRLF "\r\n"
#define PP_NAME "User-Agent: rtsp client(v1.0)"
#define PP_CRLF "\r\n"
[cpp]
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;
}
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
[cpp]
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;
}
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, "\r\nTransport: RTP/AVP/TCP;unicast;interleaved=0-1");
else
sprintf(buf, "\r\nTransport: RTP/AVP;unicast;client_port=%d-%d", ntohs(port2), ntohs(port1));
sprintf(buf2, "%s/track1 RTSP/1.0\r\n", url);
sprintf(ss, s, buf2, 3, PP_NAME, buf, PP_CRLF, PP_CRLF);
return ss;
}
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, "\r\nTransport: RTP/AVP/TCP;unicast;interleaved=0-1");
else
sprintf(buf, "\r\nTransport: RTP/AVP;unicast;client_port=%d-%d", ntohs(port2), ntohs(port1));
sprintf(buf2, "%s/track1 RTSP/1.0\r\n", url);
sprintf(ss, s, buf2, 3, PP_NAME, buf, PP_CRLF, PP_CRLF);
return ss;
}
4.PLAY
[cpp]
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\r\n", session);
sprintf(ss, s, url, 4, session, range, PP_NAME, PP_CRLF, PP_CRLF);
return ss;
}
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\r\n", session);
sprintf(ss, s, url, 4, session, range, PP_NAME, PP_CRLF, PP_CRLF);
return ss;
}