RTSP调试代码

 

#ifdef _WIN32_WCE

#include "stdafx.h"

#endif





#ifndef _WIN32_WCE

#define WIN32_LEAN_AND_MEAN

#endif





#include <windows.h>

#include <commctrl.h>





#include <MMSystem.h>





#include <winsock2.h>





#include <stdio.h>

#include <stdlib.h>

#include <tchar.h>





#ifdef _WIN32_WCE

#pragma comment(lib, "ws2.lib")

#else

#pragma comment(lib, "ws2_32.lib")

#endif





#define  PP_NAME "User-Agent: rtsp client(v1.0)"

#define  PP_CRLF "\r\n"





//打开连接;

long InitSocket();





//关闭连接;

long DeInitSocket();





//初始化tcp socket;

long InitTCPSocket(int port);





//初始化udp socket;

long InitUDPSocket(const char *ip, int port);





//取socket端口号;

long GetSokcetPort(int sock, int *port);





//读取数据;

long ReadSocket(int sock, char *buf, int len, int timeout);





//发送命令数据;

long SendRTSPCmd(int sock, const char *cmd, const char *szparam);





//解析rtsp命令回应数据;

long PraseRTSPCmd();

long PraseOptionCmd(const char *sz);

long PraseDescribeCmd(const char *sz);

long PraseSetupCmd(const char *sz, char *sess);

long PrasePlayCmd(const char *sz);

long GetResponseCode(const char *sz);  //取返回值;





//////////////////////////////////////////////////////////////////////////

//字符串操作函数;

static char* getLine(char* startOfLine);









//生成rtsp发送命令;

char * GetRTSPCmd(const char *);

char * GetOptionCmd(char *url);

char * GetDescribeCmd(char *url);

char * GetPlayCmd(char *url, char *session, char *range);

char * GetSetupCmd(char *url, int port1, int port2);





char * GetReportCmd(char *);





//////////////////////////////////////////////////////////////////////////

//日志函数;

long logwr(void *, int len);





//全局变量定义区;

fd_set rfdsock;

//日志写入文件指针;

FILE *fp = NULL;

//





//////////////////////////////////////////////////////////////////////////

//rtsp请求解析;

long PraseURL(const char *url, char *szip, int *iport);

int _tmain(int argc, _TCHAR* argv[])

{

	int sockin, sc1, sc2;

	sockaddr_in addr;

	char *buf, *szcmd, *url;

	char szip[32];

	int nlen, iret, iport;

	int ip1, ip2;

	long lret;





	//初始化变量;

	FD_ZERO(&rfdsock);





	fp = fopen("rtsp_log.txt", "w+");

	//分配缓冲区;

	nlen = 10240;

	buf = (char*)malloc(nlen);





	//定义要连接的url;

	//url = "rtsp://192.168.1.43:2554/realmp3.mp3";

	url = "rtsp://192.168.10.177/bipbop-gear1-all.ts";

	//url = "rtsp://192.168.1.43/1.amr";

	//初始化sock;

	InitSocket();





	//分析url请求,取出ip,端口;

	lret = PraseURL(url, szip, &iport);

		

	//初始化与服务器连接的socket;

	sockin = InitTCPSocket(0);





	//与服务器连接;

	addr.sin_family = AF_INET;

	addr.sin_port = htons(iport);

	addr.sin_addr.s_addr = inet_addr(szip);

	iret = connect(sockin,(struct sockaddr*)&addr, sizeof addr);





	if(iret   ==   SOCKET_ERROR)   

	{   

		int   erro   =   WSAGetLastError();   





		printf("connect   fail   !");

		Sleep(3000);     





		closesocket(sockin);   

		WSACleanup();     

		return 0;     

	} 





	//发送option命令;

	szcmd = GetOptionCmd(url);

	lret = SendRTSPCmd(sockin, "OPTIONS",szcmd);

	free(szcmd);

	lret = ReadSocket(sockin, buf, nlen,100);

	

	//发送DESCRIBE命令;

	szcmd = GetDescribeCmd(url);

	lret = SendRTSPCmd(sockin, "DESCRIBE", szcmd);

	free(szcmd);

	lret = ReadSocket(sockin, buf,  nlen, 100);





	//解析Response;

	lret = PraseDescribeCmd((const char*)buf);

	

	//创建客户端接收端口;

	sc1 = InitUDPSocket(NULL, 6544);

	sc2 = InitUDPSocket(NULL, 6545);





	//将sock加入到要等待的队列;

	FD_SET(sc1, &rfdsock );

	FD_SET(sc2, &rfdsock);

	lret = GetSokcetPort(sc1, &ip1);

	lret = GetSokcetPort(sc2, &ip2);





	//发送Setup命令,告诉服务器客户端的接受数据的端口;

	szcmd = GetSetupCmd(url, ip1, ip2);

	//告诉服务器客户端的端口;

	lret = SendRTSPCmd(sockin, "SETUP", szcmd);

	free(szcmd);

	lret = ReadSocket(sockin, buf, nlen, 100);





	//解析Response返回的命令串;

	char szip2[9];

	lret = PraseSetupCmd(buf, szip2);





	char *session, *srange;

	session = szip2;

	//发送PLAY命令

	srange  = "Range: npt=0.000-39.471\r\n";

	szcmd = GetPlayCmd(url, session, srange);

	lret = SendRTSPCmd(sockin, "PLAY", szcmd);

	free(szcmd);

	lret = ReadSocket(sockin, buf, nlen, 100);





	timeval tv;

	fd_set fr;





	int i;





	tv.tv_sec = 20;

	tv.tv_usec = 0;

	struct sockaddr_in addr2;

	int addrlen;

	addrlen = sizeof addr;





	//将数据写到文件中去;

	FILE *ffp;

	ffp = fopen("bipbop-gear1-all.ts", "w+");





	//开始接受数据了;

	while(true)

	{

		fr = rfdsock;

		lret  = select(0, &fr, NULL, NULL, &tv);





		if(lret == SOCKET_ERROR)

		{

			break;

		}

		else if(lret >0)

		{

			//判断是哪个socket可以读取数据了

			for(i = 0; i< 2;i ++)

			{

				if(FD_ISSET(rfdsock.fd_array[i], &fr)

					&& FD_ISSET(rfdsock.fd_array[i], &rfdsock))

				{

					lret = recvfrom(rfdsock.fd_array[i], buf, nlen,0, (struct sockaddr*)&addr2, &addrlen );

					if(lret > 0 && ffp)

					{

						fwrite(buf, 1, lret, ffp);

					}

					else if(lret == SOCKET_ERROR)

					{

						break;

					}

				}

			}





		}

		else if(lret == 0)

			break;

	}

	fclose(ffp);





	//退出后的清理工作

	closesocket(sockin);

	closesocket(sc1);

	closesocket(sc2);





	fwrite("\r\nend", 1, 5, fp);

	fclose(fp);

	return 0;

}





long InitSocket()

{

	WSADATA ws;

	long lret  = -1;

	lret = WSAStartup(MAKEWORD(2,2), &ws);

	return 0;

}





long DeInitSocket()

{





	WSACleanup();

	return 0;

}





long InitTCPSocket( int port )

{

	long lret ;

	int sock;

	sockaddr_in addr;

	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);





	//int flag = 1;

	//lret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&flag, sizeof flag);





	//addr.sin_family = AF_INET;

	//addr.sin_port = 0;

	//addr.sin_addr.s_addr = INADDR_ANY;

	//lret = bind(sock, (struct sockaddr*)&addr, sizeof addr);

	lret = sock;

	return lret;

}

#define   SIO_RCVALL                         _WSAIOW(IOC_VENDOR,1)   

#define   SIO_RCVALL_MCAST             _WSAIOW(IOC_VENDOR,2)   

#define   SIO_RCVALL_IGMPMCAST     _WSAIOW(IOC_VENDOR,3)   

#define   SIO_KEEPALIVE_VALS         _WSAIOW(IOC_VENDOR,4)   

#define   SIO_ABSORB_RTRALERT       _WSAIOW(IOC_VENDOR,5)   

#define   SIO_UCAST_IF                     _WSAIOW(IOC_VENDOR,6)   

#define   SIO_LIMIT_BROADCASTS     _WSAIOW(IOC_VENDOR,7)   

#define   SIO_INDEX_BIND                 _WSAIOW(IOC_VENDOR,8)   

#define   SIO_INDEX_MCASTIF           _WSAIOW(IOC_VENDOR,9)   

#define   SIO_INDEX_ADD_MCAST       _WSAIOW(IOC_VENDOR,10)   

#define   SIO_INDEX_DEL_MCAST       _WSAIOW(IOC_VENDOR,11)   

long InitUDPSocket(const char *ip,  int port )

{

	long lret;

	int sock;

	sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

	int flag = 1;

	lret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&flag, sizeof flag);





	sockaddr_in addr;





	addr.sin_family = AF_INET;

	addr.sin_port = port;

	if(ip)

		addr.sin_addr.s_addr = inet_addr(ip);

	else

		addr.sin_addr.s_addr = INADDR_ANY;

	lret = bind(sock, (struct sockaddr*)&addr, sizeof addr);

	//设置非堵塞通讯

	//u_long arg = 2; 

	//lret = ioctlsocket(sock, SIO_LIMIT_BROADCASTS, &arg);





	lret = sock;

	return lret;

}





long GetSokcetPort( int sock, int *port )

{

	long lret = -1;

	sockaddr_in addr;

	int nlen;

	nlen = sizeof addr;





	addr.sin_port = 0;





	*port = 0;





	if(getsockname(sock, (struct sockaddr*)&addr, &nlen) < 0)

		lret = -1;

	else

	{

		lret = 0;

		*port = addr.sin_port;

	}





	return lret;

}













long ReadSocket(int sock,  char *buf, int len, int timeout )

{

	long lret ;

	int iret;

	fd_set fr;

	timeval tm;

	tm.tv_sec = timeout;

	tm.tv_usec = 0;





	FD_ZERO(&fr);

	fr.fd_count = 1;

	fr.fd_array[0] = sock;





	lret = select(sock, &fr, NULL, NULL, &tm);





	if(lret > 0)

	{

		lret = recv(sock, buf, len, 0);

		if(lret == SOCKET_ERROR)

		{





		}

		else if(lret > 0)

		{

			logwr((void*)"***Recive:\r\n", 12);

			logwr((void*)buf, lret);

		}

	}





	return lret;

}





long SendRTSPCmd( int sock, const char *cmd, const char *szparam )

{

	long lret;

	int ilen;

	ilen = strlen(szparam);

	lret = send(sock, szparam, ilen,0);

	if(lret == SOCKET_ERROR)

	{

		lret = WSAGetLastError();

	}

	logwr((void*)"***Send:\r\n", 10);

	logwr((void *)szparam, ilen);

	return lret;

}





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 * 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 * 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 * 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 * 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, "SETUP %s/streamid=0 RTSP/1.0\r\n", url);

	//sprintf(ss, s, buf2, 3,  buf, PP_NAME, PP_CRLF, PP_CRLF);

	sprintf(buf2, "%s/track1 RTSP/1.0\r\n", url);

	sprintf(ss, s, buf2, 3,  PP_NAME, buf, PP_CRLF, PP_CRLF);





	return ss;

}





long PraseURL( const char *url, char *szip, int *iport )

{

	long lret = -1;

	if(url)

	{ 

		//找到了rtsp这个标识符

		if(!_strnicmp(url, "rtsp://", 7))

		{

			//找ip

			char *s, *ss;

			s = (char*)url + strlen("rtsp://");

			ss = strchr(s, '/');





			strncpy(szip, s,  ss- s);

			szip[ss -s] = '\0';





			//查找下是否是有端口设置

			s = strchr(szip, ':');

			//有端口设置

			if(s)

			{

				ss = s;

				s ++;

				*iport = atoi(s);





				//同时修正ip地址

				szip[ss - szip] = '/0';

			}

			else

				*iport = 554;





			lret = 0;

		}

	}









	return lret;

}





long logwr( void *data, int len )

{

	long lret = -1;

	if(fp)

		lret = fwrite(data, 1, len, fp);

	

	return lret;

}









static char* getLine(char* startOfLine) {

	// returns the start of the next line, or NULL if none

	for (char* ptr = startOfLine; *ptr != '\0'; ++ptr) {

		// Check for the end of line: \r\n (but also accept \r or \n by itself):

		if (*ptr == '\r' || *ptr == '\n') {

			// We found the end of the line

			if (*ptr == '\r') {

				*ptr++ = '\0';

				if (*ptr == '\n') ++ptr;

			} else {

				*ptr++ = '\0';

			}

			return ptr;

		}

	}





	return NULL;

}





long GetResponseCode( const char *sz )

{

	long lret = -1;

	if(sz)

	{

		if(sscanf(sz, "%*s%u", &lret) != 1)

			;

	}





	return lret;

}





long PraseDescribeCmd( const char *sz )

{

	long lret = -1;

	char *ss, *szst;

	szst = (char *)sz;

	int contentLength = -1;





	if(GetResponseCode(sz )== 200)

	{

		ss= getLine(szst);

		while(1)

		{

			ss = getLine(ss);

			if(ss == NULL)

				break;

			if (sscanf(ss, "Content-Length: %d", &contentLength) == 1

				|| sscanf(ss, "Content-length: %d", &contentLength) == 1) {

					if (contentLength < 0) {

						//....

					}

			}

		}

	}





	return lret;

}





long PraseSetupCmd( const char *sz , char *sess)

{

	long lret = -1;

	char *ss, *szst;

	szst = (char *)sz;

	int contentLength = -1;





	if(GetResponseCode(sz )== 200)

	{

		ss= getLine(szst);

		while(1)

		{

			ss = getLine(ss);

			if(ss == NULL)

				break;

			if (sscanf(ss, "Session: %sP4 192.168.10.177", sess) == 1)

			{

				lret = 1;

				return lret;

			}

		}





	}

	return lret;

}


 

 

你可能感兴趣的:(代码)