# 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" // open the connection; long InitSocket (); // close the connection; long DeInitSocket (); // initialize tcp socket; long InitTCPSocket (int port ); // initialize udp socket; long InitUDPSocket (const char * ip, int port); // obtain the socket port number; long GetSokcetPort (int sock, int * port); // read data; long ReadSocket (int sock, char * buf, int len, int timeout); // send command data; long SendRTSPCmd (int sock, const char * cmd, const char * szparam ); // parse the rtsp command to respond to data; long Pr AseRTSPCmd (); 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); // return value; //////////////////////////////////////// /// // string operation function; static char * getLine (char * startOfLine); // generates the rtsp sending command; 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 *); //////////////////////////////////////// /// // log function; long logwr (void *, int len); // global variable definition area; fd_set rfdsock; // log Writing FILE pointer; FILE * fp = NULL; //////////////////////////////// //////////////////////////////////////// ////// Parse the rtsp request; 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; // initialization variable; FD_ZERO (& rfdsock); fp = fopen ("rtsp_log.txt", "w +"); // allocate a buffer; nlen = 10240; buf = (char *) malloc (nlen ); // define the connection 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"; // initialize sock; InitSocket (); // analyze the url request and retrieve the ip address and port; lret = PraseURL (url, szip, & iport ); // initialize the socket connected to the server; sockin = InitTCPSocket (0); // connect to the server; addr. sin_family = AF_INET; addr. sin_port = htons (iport); addr. sin_addr.s_addr = inet_addr (szip); iret = connect (sockin, (st Ruct sockaddr *) & addr, sizeof addr); if (iret = SOCKET_ERROR) {int erro = WSAGetLastError (); printf ("connect fail! "); Sleep (3000); closesocket (sockin); WSACleanup (); return 0;} // send the option command; szcmd = GetOptionCmd (url); lret = SendRTSPCmd (sockin, "OPTIONS", szcmd); free (szcmd); lret = ReadSocket (sockin, buf, nlen, 100); // send the DESCRIBE command; szcmd = GetDescribeCmd (url ); lret = SendRTSPCmd (sockin, "DESCRIBE", szcmd); free (szcmd); lret = ReadSocket (sockin, buf, nlen, 100); // parse Response; lret = PraseDescribeCmd (const cha R *) buf); // create a client receiving port; sc1 = InitUDPSocket (NULL, 6544); sc2 = InitUDPSocket (NULL, 6545 ); // Add sock to the queue to be waited; FD_SET (sc1, & rfdsock); FD_SET (sc2, & rfdsock); lret = GetSokcetPort (sc1, & ip1 ); lret = GetSokcetPort (sc2, & ip2); // send the Setup command to inform the Server client of the port for receiving data; szcmd = GetSetupCmd (url, ip1, ip2 ); // tell the Server client port; lret = SendRTSPCmd (sockin, "SETUP", szcmd); free (szcmd); lret = ReadSocket (sockin, buf, nlen, 100 ); // Parse the command string returned by Response; char szip2 [9]; lret = PraseSetupCmd (buf, szip2); char * session, * srange; session = szip2; // send the PLAY command srange = "Range: Treaty = 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 addrle N; addrlen = sizeof addr; // write data to the FILE; FILE * ffp; ffp = fopen ("bipbop-gear1-all.ts", "w + "); // start to accept data; while (true) {fr = rfdsock; lret = select (0, & fr, NULL, NULL, & TV); if (lret = SOCKET_ERROR) {break;} else if (lret> 0) {// determine which socket can read data 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, nle N, 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), & 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 rule _ WSAIOW (IOC_VENDOR, 3) # define rule _ WSAIOW (IOC_VENDOR, 4) # define rule _ WSAIOW (IOC_VENDOR, 5) # define rule _ WSAIOW (IOC_VENDOR, 6) # define SIO_LIMIT_BROADCASTS _ WSAIOW (IOC_VENDOR, 7) # define SIO_INDEX _ BIND _ WSAIOW (IOC_VENDOR, 8) # define evaluate _ WSAIOW (IOC_VENDOR, 9) # define evaluate _ WSAIOW (IOC_VENDOR, 10) # define evaluate _ 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); sockad Dr_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); // set non-blocking communication // 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 nle N; 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 "" % s ";} else if (! Strcmp (szName, "PLAY") {cmdFmt = "PLAY % s RTSP/1.0 \ r \ n" "CSeq: % d \ r \ n" "Session: % s \ r \ n "" % 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 RTSP/1.0 \ r \ n" "CSeq: % d \ r \ n "" Session: % s \ r \ n "" Range: NTS = 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" "% 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 "" % 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 "# 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 "" % s ";} else if (! Strcmp (szName, "SETUP") {cmdFmt = "SETUP % s" "CSeq: % d \ r \ n "" % 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 * ur L) {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_NA ME) + 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, & quot; SETUP % s/streamid = 0 RTSP/1.0 \ r \ n & quot;, 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) {// locate the rtsp Identifier if (! _ Strnicmp (url, "rtsp: //", 7) {// find ip char * s, * ss; s = (char *) url + strlen ("rtsp: // "); ss = strchr (s, '/'); strncpy (szip, s, ss-s); szip [ss-s] = '\ 0 '; // check whether the port is configured with s = strchr (szip, ':'); // if (s) {ss = s; s ++; * iport = atoi (s); // fixed the IP address szip [ss-szip] = '/0' at the same time;} 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 ;}