RTSP protocol debugging program

Source: Internet
Author: User

Recently, When I port the RTSP library to wince, I cannot read the data. To solve the problem, I wrote a small RTSP client protocol learning program to implement basic session protocols, options, describe, setup, play and other protocols to save the read data to the file. The program code is pasted below, which can run on ce and PC. For your sharing.

# 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"

// Use for testing

// 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 the data
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); // Return Value

//////////////////////////////////////// //////////////////////////////////
// String operation function
Static char * Getline (char * startofline );

// Generate 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 Functions
Long logwr (void *, int Len );

// Global variable definition Area
Fd_set rfdsock;
// Log Writing File pointer
File * fp = NULL;
//

//////////////////////////////////////// //////////////////////////////////
// RTSP request Parsing
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;

// Initialize the variable
Fd_zero (& rfdsock );

Fp = fopen ("1.txt"," W + ");
// Allocate a buffer
Nlen = 10240;
Buf = (char *) malloc (nlen );

// Define the URL to be connected
// URL = "rtsp: // 192.168.1.43: 2554/realmp3.mp3 ";
Url = "rtsp: // 192.168.1.42/realmp3.mp3 ";
// 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, (struct sockaddr *) & ADDR, sizeof ADDR );

// Send the option command
Szcmd = getoptioncmd (URL );
LRET = sendrtspcmd (sockin, "options", szcmd );
Free (szcmd );

LRET = readsocket (FIG, Buf, nlen, 100 );

 
// Send the describe command
Szcmd = getdescribecmd (URL );
LRET = sendrtspcmd (sockin, "describe", szcmd );
Free (szcmd );
LRET = readsocket (FIG, Buf, nlen, 100 );
 
// Parse response
LRET = prasedescribecmd (const char *) BUF );

// Create a client receiving port
SC1 = initudpsocket (null, 6544 );
SC2 = initudpsocket (null, 6545 );

// Add sock to the queue to wait
 
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 (FIG, Buf, nlen, 100 );
// Parse the command string returned by Response
LRET = prasesetupcmd (BUF, szip );

Char * session, * srange;
Session = szip;
// 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 (FIG, 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;

// Write data to a file
File * FFP;
FFP = fopen ("1.mp3", "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, 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 );

// Cleanup after exiting
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 );
// 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 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 *) 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 *) 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 =
& Quot; record % S % s RTSP/1.0/R/N & quot"
"CSeq: % d/R/N"
"Session: % S/R/N"
"Range: Treaty = 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 =
& Quot; get_parameter % s RTSP/1.0/R/N & quot"
"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 =
"% 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, 1, 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, 1, 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, "Transport: RTP/AVP/tcp; unicast; interleaved = 0-1 ");
Else
Sprintf (BUF, "Transport: RTP/AVP; unicast; client_port = % d-% d/R/N", ntohs (port2), ntohs (port1 ));
Sprintf (buf2, "setup % S/streamid = 0 RTSP/1.0/R/N", URL );

Sprintf (SS, S, buf2, 1, Buf, pp_name, pp_crlf, pp_crlf );

Return SS;
}

Long praseurl (const char * URL, char * szip, int * iport)
{
Long LRET =-1;
If (URL)
{
// The identifier RTSP is found.
If (! _ Strnicmp (URL, "rtsp: //", 7 ))
{
// Find the IP address
Char * s, * ss;
S = (char *) URL + strlen ("rtsp ://");
Ss = strchr (S ,'/');

Strncpy (szip, S, SS-S );
Szip [ss-S] = '/0 ';

// Check whether port settings exist.
S = strchr (szip ,':');
// With port settings
If (s)
{
Ss = s;
S ++;
* Iport = atoi (s );

// Modify the IP address at the same time
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: % [^;]", sess) = 1)
{
LRET = 1;
}
}

}
Return LRET;
}

This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/nxjbill/archive/2010/01/05/5137178.aspx

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.