Posted By:
dev_dud
Posted On:
Saturday, April 7, 2007 10:28 PM
Hello All, I am new on this site, but have heard a lot about it.I have written an rtsp server which ideally should accept the requests from multiple clients. But I guess i am making some mistake in that. I am writing th code along with this mail.....please let me know where i am making mistake.....i would appreciate that. When I run the two clients it wont work....i mean the second client would not be able to get conected to the server.. Server code.............. /* ------------------ Server usage: java Server [RTSP listening port] ---------------------- */ //Written by University of Maryland //Edited by group: Protocol 5.0 packag
More>>
Hello All,
I am new on this site, but have heard a lot about it.I have written an rtsp server which ideally should accept the requests from multiple clients. But I guess i am making some mistake in that. I am writing th code along with this mail.....please let me know where i am making mistake.....i would appreciate that.
When I run the two clients it wont work....i mean the second client would not be able to get conected to the server..
Server code..............
/* ------------------
Server
usage: java Server [RTSP listening port]
---------------------- */
//Written by University of Maryland
//Edited by group: Protocol 5.0
package rtsp;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.Timer;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLServerSocketFactory;
//TO COMPILE: javac Server.java
//TO RUN WITHOUT SSL: java Server
.
//WHERE: listen_port is a number greater than 1024
//WHERE: . is a flag to tell the program no SSL is used
//TO RUN WITH SSL: java -Djavax.net.ssl.keyStore=RTSPkey -Djavax.net.ssl.keyStorePassword=123456
!
//WHERE: RTSPkey is the certificate given by the CA or the keytool java utility
//WHERE: 123456 is the password associated with the certificate
//WHERE: listen_port is a number greater than 1024
//WHERE: ! is a flag to tell the program to use SSL
public class Server extends JFrame implements ActionListener, Runnable {
//RTP variables:
//----------------
DatagramSocket RTPsocket; //socket to be used to send and receive UDP packets
DatagramPacket senddp; //UDP packet containing the video frames
static int count;
static int count1;
InetAddress ClientIPAddr; //Client IP address
int RTP_dest_port = 0; //destination port for RTP packets (given by the RTSP Client)
//GUI:
//----------------
JLabel label;
//Video variables:
//----------------
int imagenb = 0; //image nb of the image currently transmitted
VideoStream video; //VideoStream object used to access video frames
static int MJPEG_TYPE = 26; //RTP payload type for MJPEG video
static int FRAME_PERIOD = 100; //Frame period of the video to stream, in ms
static int VIDEO_LENGTH = 500; //length of the video in frames
Timer timer; //timer used to send the images at the video frame rate
byte[] buf; //buffer used to store the images to send to the client
//RTSP variables
//----------------
//rtsp states
final static int INIT = 0;
final static int READY = 1;
final static int PLAYING = 2;
//rtsp message types
final static int SETUP = 3;
final static int PLAY = 4;
final static int PAUSE = 5;
final static int TEARDOWN = 6;
static int state; //RTSP Server state == INIT or READY or PLAY
SSLSocket RTSPsocket2; //socket used to send/receive RTSP messages
Socket RTSPsocket[]= new Socket[10]; //socket used to send/receive RTSP messages
//input and output stream filters
static BufferedReader RTSPBufferedReader;
static BufferedWriter RTSPBufferedWriter;
static String VideoFileName; //video file requested from the client
static int RTSP_ID = 123456; //ID of the RTSP session
int RTSPSeqNb = 0; //Sequence number of RTSP messages within the session
final static String CRLF = "
";
//--------------------------------
//Constructor
//--------------------------------
public Server(){
//init Frame
super("Server");
//init Timer
timer = new Timer(FRAME_PERIOD, this);
timer.setInitialDelay(0);
timer.setCoalesce(true);
//allocate memory for the sending buffer
buf = new byte[15000];
//Handler to close the main window
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
//stop the timer and exit
timer.stop();
System.exit(0);
}});
//GUI:
label = new JLabel("Send frame # ", JLabel.CENTER);
getContentPane().add(label, BorderLayout.CENTER);
}
//------------------------------------
//main
//------------------------------------
public static void main(String argv[]) throws Exception
{
//create a Server object
Server theServer = new Server();
//show GUI:
theServer.pack();
theServer.setVisible(true);
//get RTSP socket port from the command line
int RTSPport = Integer.parseInt(argv[0]);
//Initiate TCP connection with the client for the RTSP session
//
//ADDED CODE
if(argv[1].equals("!"))
{
SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket listenSocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(RTSPport);
theServer.RTSPsocket2 = (SSLSocket)listenSocket.accept();
listenSocket.close();
theServer.ClientIPAddr = theServer.RTSPsocket2.getInetAddress();
RTSPBufferedReader = new BufferedReader(new InputStreamReader(theServer.RTSPsocket2.getInputStream()) );
RTSPBufferedWriter = new BufferedWriter(new OutputStreamWriter(theServer.RTSPsocket2.getOutputStream()) );
}
else
{
ServerSocket listenSocket = new ServerSocket(RTSPport);
theServer.RTSPsocket[count] = (Socket)listenSocket.accept();
// listenSocket.close();
System.out.println("the socket is "+theServer.RTSPsocket[count]);
count1=count;
count++;
System.out.println("after socket creation"+count1);
//listenSocket.close();
Thread t = new Thread(theServer);
t.start();
}
//END ADDED CODE
//Get Client IP address
//Initiate RTSPstate
}
public void run(){
try
{
System.out.println("inside run");
this.ClientIPAddr = this.RTSPsocket[count1].getInetAddress();
RTSPBufferedReader = new BufferedReader(new InputStreamReader(RTSPsocket[count1].getInputStream()) );
RTSPBufferedWriter = new BufferedWriter(new OutputStreamWriter(RTSPsocket[count1].getOutputStream()) );
}catch(IOException e)
{
System.out.println("in or out failed");
System.exit(-1);
}
state = INIT;
//Set input and output stream filters:
//Wait for the SETUP message from the client
int request_type;
boolean done = false;
while(!done)
{
request_type = this.parse_RTSP_request(); //blocking
if (request_type == SETUP)
{
done = true;
//update RTSP state
state = READY;
System.out.println("New RTSP state: READY");
//Send response
this.send_RTSP_response();
//init the VideoStream object:
try
{
this.video = new VideoStream(VideoFileName);
//init RTP socket
this.RTPsocket = new DatagramSocket();
}catch(Exception ex)
{
}
}
}
//loop to handle RTSP requests
while(true)
{
//parse the request
request_type = this.parse_RTSP_request(); //blocking
if ((request_type == PLAY) && (state == READY))
{
//send back response
this.send_RTSP_response();
//start timer
this.timer.start();
//update state
state = PLAYING;
System.out.println("New RTSP state: PLAYING");
}
else if ((request_type == PAUSE) && (state == PLAYING))
{
//send back response
this.send_RTSP_response();
//stop timer
this.timer.stop();
//update state
state = READY;
System.out.println("New RTSP state: READY");
}
else if (request_type == TEARDOWN)
{
//send back response
this.send_RTSP_response();
//stop timer
this.timer.stop();
//close sockets
try
{
this.RTSPsocket[count1].close();
}catch(Exception ex)
{
}
this.RTPsocket.close();
System.exit(0);
}
}
}
//------------------------
//Handler for timer
//------------------------
public void actionPerformed(ActionEvent e) {
//if the current image nb is less than the length of the video
if (imagenb
< VIDEO_LENGTH)
{
//update current imagenb
imagenb++;
try {
//get next frame to send from the video, as well as its size
int image_length = video.getnextframe(buf);
//Builds an RTPpacket object containing the frame
RTPpacket rtp_packet = new RTPpacket(MJPEG_TYPE, imagenb, imagenb*FRAME_PERIOD, buf, image_length);
//get to total length of the full rtp packet to send
int packet_length = rtp_packet.getlength();
//retrieve the packet bitstream and store it in an array of bytes
byte[] packet_bits = new byte[packet_length];
rtp_packet.getpacket(packet_bits);
//send the packet as a DatagramPacket over the UDP socket
senddp = new DatagramPacket(packet_bits, packet_length, ClientIPAddr, RTP_dest_port);
RTPsocket.send(senddp);
System.out.println("Send frame #"+imagenb);
//print the header bitstream
rtp_packet.printheader();
//update GUI
label.setText("Send frame #" + imagenb);
}
catch(Exception ex)
{
System.out.println("Exception caught: "+ex);
System.exit(0);
}
}
else
{
//if we have reached the end of the video file, stop the timer
timer.stop();
}
}
//------------------------------------
//Parse RTSP Request
//------------------------------------
private int parse_RTSP_request()
{
int request_type = -1;
try{
//parse request line and extract the request_type:
String RequestLine = RTSPBufferedReader.readLine();
//System.out.println("RTSP Server - Received from Client:");
System.out.println(RequestLine);
StringTokenizer tokens = new StringTokenizer(RequestLine);
String request_type_string = tokens.nextToken();
//convert to request_type structure:
if ((new String(request_type_string)).compareTo("SETUP") == 0)
request_type = SETUP;
else if ((new String(request_type_string)).compareTo("PLAY") == 0)
request_type = PLAY;
else if ((new String(request_type_string)).compareTo("PAUSE") == 0)
request_type = PAUSE;
else if ((new String(request_type_string)).compareTo("TEARDOWN") == 0)
request_type = TEARDOWN;
if (request_type == SETUP)
{
//extract VideoFileName from RequestLine
VideoFileName = tokens.nextToken();
}
//parse the SeqNumLine and extract CSeq field
String SeqNumLine = RTSPBufferedReader.readLine();
System.out.println(SeqNumLine);
tokens = new StringTokenizer(SeqNumLine);
tokens.nextToken();
RTSPSeqNb = Integer.parseInt(tokens.nextToken());
//get LastLine
String LastLine = RTSPBufferedReader.readLine();
System.out.println(LastLine);
if (request_type == SETUP)
{
//extract RTP_dest_port from LastLine
tokens = new StringTokenizer(LastLine);
for (int i=0; i
<3; i++)
tokens.nextToken(); //skip unused stuff
RTP_dest_port = Integer.parseInt(tokens.nextToken());
}
//else LastLine will be the SessionId line ... do not check for now.
}
catch(Exception ex)
{
System.out.println("Exception caught: "+ex);
System.exit(0);
}
return(request_type);
}
//------------------------------------
//Send RTSP Response
//------------------------------------
private void send_RTSP_response()
{
System.out.println("inside response"+count1);
try{
RTSPBufferedWriter.write("RTSP/1.0 200 OK"+CRLF);
RTSPBufferedWriter.write("CSeq: "+RTSPSeqNb+CRLF);
RTSPBufferedWriter.write("Session: "+RTSP_ID+CRLF);
RTSPBufferedWriter.flush();
//System.out.println("RTSP Server - Sent response to Client.");
}
catch(Exception ex)
{
System.out.println("Exception caught: "+ex);
System.exit(0);
}
}
}
Any help would be appreciated......
Thanks,
Deval
<<Less