整理了下之前文章提到的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\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
#define PP_NAME "User-Agent: rtsp client(v1.0)" #define PP_CRLF "\r\n"
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, "\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
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; }