RTSP(Real Time Streaming Protocol)是由Real Network和Netscape共同提出的如何有效地在IP网络上传输流媒体数据的应用层协议。RTSP对流媒体提供了诸如暂停,快进等控制,而它本身并不传输数据,RTSP的作用相当于流媒体服务器的远程控制。服 务器端可以自行选择使用TCP或UDP来传送串流内容,它的语法和运作跟HTTP 1.1类似,但并不特别强调时间同步,所以比较能容忍网络延迟。而且允许同时多个串流需求控制(Multicast),除了可以降低服务器端的网络用量, 还可以支持多方视频会议(Video  onference)。 因为与HTTP1.1的运作方式相似,所以代理服务器《Proxy》的快取功能《Cache》也同样适用于RTSP,并因RTSP具有重新导向功能,可视 实际负载情况来转换提供服务的服务器,以避免过大的负载集中于同一服务器而造成延迟。
   

rtsp和http的区别和联系

    (1)联系:两者都用纯文本来发送消息,且rtsp协议的语法也和HTTP类似。Rtsp一开始这样设计,也是为了能够兼容使用以前写的HTTP协议分析代码
    (2)区别:rtsp
是有状态的,不同的是RTSP的命令需要知道现在正处于一个什么状态,也就是说rtsp的命令总是按照顺序来发送,某个命令总在另外一个命令之前要发送。
Rtsp不管处于什么状态都不会去断掉连接。,而http则不保存状态,协议在发送一个命令以后,连接就会断开,且命令之间是没有依赖性的。rtsp协议使用554端口,http使用80端口。
rtsp和sip的区别和联系
 
SIP(Session
Initiation
Protocol),是基于IP的一个应用层控制协议。由于SIP是基于纯文本的信令协议,可以管理不同接入网络上的会话等。会话可以是终端设备之间任何
类型的通信,如视频会话、既时信息处理或协作会话。该协议不会定义或限制可使用的业务,传输、服务质量、计费、安全性等问题都由基本核心网络和其它协议处
理。
 

(1)联系:sip和rtsp都是应用层的控制协议,负责一次通信过程的建立和控制和结束,不负责中间的传输部分。他们都是基于纯文本的信令协议,穿墙性
能良好。支持tcp、udp,支持多方通信。他们都需要服务器支持,都支持会话中重定向。sip和rtsp
都使用sdp协议来传送媒体参数,使用rtp(rtcp)协议来传输媒体流。

(2)区别:rtsp是专门为流媒体制定的协议,在多个媒体流的时间同步方面比sip强大。rtsp还提供网络负载均衡的功能,减轻服务器压力和网络带宽
要求。sip一般用来创建一次音频、视频通话(双向),而rtsp一般用来做视频点播、视频监控等(单向)。当然,从原理上讲,rtsp也可以做双向的视
频通话。

 
RTSP和RTP(rtcp)的关系
RTSP的消息
       RTSP的消息有两大类,一是请求消息(request),一是回应消息(response),两种消息的格式不同。
 
请求消息格式:
       方法 URI RTSP版本 CR LF
       消息头 CR LF CR LF        
       消息体 CR LF

其中方法包括OPTIONS、SETUP、PLAY、TEARDOWN等待,URI是接收方(服务端)的地址,例
如:rtsp://192.168.22.136:5000/v0,每行后面的CR
LF表示回车换行,需要接收端有相应的解析,最后一个消息头需要有两个CR LF。

回应消息格式:
       RTSP版本 状态码 解释 CR LF
       消息头 CR LF CR LF
       消息体 CR LF
    其中RTSP版本一般都是RTSP/1.0,状态码是一个数值,200表示成功,解释是与状态码对应的文本解释。

状态码由三位数组成,表示方法执行的结果,定义如下:

1XX:保留,将来使用;

2XX:成功,操作被接收、理解、接受(received,understand,accepted);

3XX:重定向,要完成操作必须进行进一步操作;

4XX:客户端出错,请求有语法错误或无法实现;

5XX:服务器出错,服务器无法实现合法的请求。

RTSP的方法
rtsp中定义的方法有:OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, SCALE, GET_PARAMETER ,SET_PARAMETER 
 
1.OPTION
目的是得到服务器提供的可用方法:
OPTIONS rtsp://192.168.20.136:5000/xxx666 RTSP/1.0
CSeq: 1         //每个消息都有序号来标记,第一个包通常是option请求消息
User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10)
服务器的回应信息包括提供的一些方法,例如:
RTSP/1.0 200 OK
Server: UServer 0.9.7_rc1
Cseq: 1         //每个回应消息的cseq数值和请求消息的cseq相对应
Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, SCALE, GET_PARAMETER //服务器提供的可用的方法
 
2.DESCRIBE
C向S发起DESCRIBE请求,为了得到会话描述信息(SDP):
DESCRIBE rtsp://192.168.20.136:5000/xxx666 RTSP/1.0
CSeq: 2
token:
Accept: application/sdp
User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10)
服务器回应一些对此会话的描述信息(sdp):
RTSP/1.0 200 OK
Server: UServer 0.9.7_rc1
Cseq: 2
x-prev-url: rtsp://192.168.20.136:5000
x-next-url: rtsp://192.168.20.136:5000
x-Accept-Retransmit: our-retransmit
x-Accept-Dynamic-Rate: 1
Cache-Control: must-revalidate
Last-Modified: Fri, 10 Nov 2006 12:34:38 GMT
Date: Fri, 10 Nov 2006 12:34:38 GMT
Expires: Fri, 10 Nov 2006 12:34:38 GMT
Content-Base: rtsp://192.168.20.136:5000/xxx666/
Content-Length: 344
Content-Type: application/sdp
v=0        //以下都是sdp信息
o=OnewaveUServerNG 1451516402 1025358037 IN IP4 192.168.20.136
s=/xxx666
u=http:///
e=admin@
c=IN IP4 0.0.0.0
t=0 0
a=isma-compliance:1,1.0,1
a=range:npt=0-
m=video 0 RTP/AVP 96    //m表示媒体描述,下面是对会话中视频通道的媒体描述
a=rtpmap:96 MP4V-ES/90000
a=fmtp:96 profile-level-id=245;config=000001B0F5000001B509000001000000012000C888B0E0E0FA62D089028307
a=control:trackID=0//trackID=0表示视频流用的是通道0
 
3.SETUP
客户端提醒服务器建立会话,并确定传输模式:
SETUP rtsp://192.168.20.136:5000/xxx666/trackID=0 RTSP/1.0    
CSeq: 3
Transport: RTP/AVP/TCP;unicast;interleaved=0-1      
User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10)
//uri
中带有trackID=0,表示对该通道进行设置。Transport参数设置了传输模式,包的结构。接下来的数据包头部第二个字节位置就是
interleaved,它的值是每个通道都不同的,trackID=0的interleaved值有两个0或1,0表示rtp包,1表示rtcp包,接
受端根据interleaved的值来区别是哪种数据包。
服务器回应信息:
RTSP/1.0 200 OK
Server: UServer 0.9.7_rc1
Cseq: 3
Session: 6310936469860791894     //服务器回应的会话标识符
Cache-Control: no-cache
Transport: RTP/AVP/TCP;unicast;interleaved=0-1;ssrc=6B8B4567
 
4.PLAY
客户端发送播放请求:
PLAY rtsp://192.168.20.136:5000/xxx666 RTSP/1.0
CSeq: 4
Session: 6310936469860791894
Range: npt=0.000-      //设置播放时间的范围
User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10)
服务器回应信息:
RTSP/1.0 200 OK
Server: UServer 0.9.7_rc1
Cseq: 4
Session: 6310936469860791894
Range: npt=0.000000-
RTP-Info: url=trackID=0;seq=17040;rtptime=1467265309     
//seq和rtptime都是rtp包中的信息
 
5.TEARDOWN
客户端发起关闭请求:
TEARDOWN rtsp://192.168.20.136:5000/xxx666 RTSP/1.0
CSeq: 5
Session: 6310936469860791894
User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10)
服务器回应:
RTSP/1.0 200 OK
Server: UServer 0.9.7_rc1
Cseq: 5
Session: 6310936469860791894
Connection: Close
以上方法都是交互过程中最为常用的,其它还有一些重要的方法如get/set_parameter,pause,redirect等等
 
ps:
sdp的格式
v=<version>
o=<username> <session id> <version> <network type> <address type> <address>
s=<session name>
i=<session description>
u=<URI>
e=<email address>
p=<phone number>
c=<network type> <address type> <connection address>
b=<modifier>:<bandwidth-value>
t=<start time> <stop time>
r=<repeat interval> <active duration> <list of offsets from start-time>
z=<adjustment time> <offset> <adjustment time> <offset> ....
k=<method>
k=<method>:<encryption key>
a=<attribute>
a=<attribute>:<value>
m=<media> <port> <transport> <fmt list>
v = (协议版本)
o = (所有者/创建者和会话标识符)
s = (会话名称)
i = * (会话信息)
u = * (URI 描述)
e = * (Email 地址)
p = * (电话号码)
c = * (连接信息)
b = * (带宽信息)
z = * (时间区域调整)
k = * (加密密钥)
a = * (0 个或多个会话属性行)
时间描述:
t = (会话活动时间)
r = * (0或多次重复次数)
媒体描述:
m = (媒体名称和传输地址)
i = * (媒体标题)
c = * (连接信息 — 如果包含在会话层则该字段可选)
b = * (带宽信息)
k = * (加密密钥)
a = * (0 个或多个媒体属性行)
RTSP客户端的JAVA实现


3.1  接口IEvent.java 

接口IEvent.java的代码如下:

  1. package com.amigo.rtsp;
  2. import java.io.IOException;
  3. import java.nio.channels.SelectionKey;
  4. /** *//**
  5. * IEvent.java 网络事件处理器,当Selector可以进行操作时,调用这个接口中的方法.
  6. * 2007-3-22 下午03:35:51
  7. * @author sycheng
  8. * @version 1.0
  9. */
  10. public interface IEvent {
  11. /** *//**
  12. * 当channel得到connect事件时调用这个方法.
  13. * @param key
  14. * @throws IOException
  15. */
  16. void connect(SelectionKey key) throws IOException;
  17. /** *//**
  18. * 当channel可读时调用这个方法.
  19. * @param key
  20. * @throws IOException
  21. */
  22. void read(SelectionKey key) throws IOException;
  23. /** *//**
  24. * 当channel可写时调用这个方法.
  25. * @throws IOException
  26. */
  27. void write() throws IOException;
  28. /** *//**
  29. * 当channel发生错误时调用.
  30. * @param e
  31. */
  32. void error(Exception e);
  33. }

3.2  RTSP的测试类:RTSPClient.java
        RTSP的测试类RTSPClient.java类的代码如下所示:

  1. package com.amigo.rtsp;
  2. import java.io.IOException;
  3. import java.net.InetSocketAddress;
  4. import java.nio.ByteBuffer;
  5. import java.nio.channels.SelectionKey;
  6. import java.nio.channels.Selector;
  7. import java.nio.channels.SocketChannel;
  8. import java.util.Iterator;
  9. import java.util.concurrent.atomic.AtomicBoolean;
  10. public class RTSPClient extends Thread implements IEvent {
  11. private static final String VERSION = " RTSP/1.0/r/n";
  12. private static final String RTSP_OK = "RTSP/1.0 200 OK";
  13. /** *//** 远程地址 */
  14. private final InetSocketAddress remoteAddress;
  15. /** *//** * 本地地址 */
  16. private final InetSocketAddress localAddress;
  17. /** *//** * 连接通道 */
  18. private SocketChannel socketChannel;
  19. /** *//** 发送缓冲区 */
  20. private final ByteBuffer sendBuf;
  21. /** *//** 接收缓冲区 */
  22. private final ByteBuffer receiveBuf;
  23. private static final int BUFFER_SIZE = 8192;
  24. /** *//** 端口选择器 */
  25. private Selector selector;
  26. private String address;
  27. private Status sysStatus;
  28. private String sessionid;
  29. /** *//** 线程是否结束的标志 */
  30. private AtomicBoolean shutdown;
  31. private int seq=1;
  32. private boolean isSended;
  33. private String trackInfo;
  34. private enum Status {
  35. init, options, describe, setup, play, pause, teardown
  36. }
  37. public RTSPClient(InetSocketAddress remoteAddress,
  38. InetSocketAddress localAddress, String address) {
  39. this.remoteAddress = remoteAddress;
  40. this.localAddress = localAddress;
  41. this.address = address;
  42. // 初始化缓冲区
  43. sendBuf = ByteBuffer.allocateDirect(BUFFER_SIZE);
  44. receiveBuf = ByteBuffer.allocateDirect(BUFFER_SIZE);
  45. if (selector == null) {
  46. // 创建新的Selector
  47. try {
  48. selector = Selector.open();
  49. } catch (final IOException e) {
  50. e.printStackTrace();
  51. }
  52. }
  53. startup();
  54. sysStatus = Status.init;
  55. shutdown=new AtomicBoolean(false);
  56. isSended=false;
  57. }
  58. public void startup() {
  59. try {
  60. // 打开通道
  61. socketChannel = SocketChannel.open();
  62. // 绑定到本地端口
  63. socketChannel.socket().setSoTimeout(30000);
  64. socketChannel.configureBlocking(false);
  65. socketChannel.socket().bind(localAddress);
  66. if (socketChannel.connect(remoteAddress)) {
  67. System.out.println("开始建立连接:" + remoteAddress);
  68. }
  69. socketChannel.register(selector, SelectionKey.OP_CONNECT
  70. | SelectionKey.OP_READ | SelectionKey.OP_WRITE, this);
  71. System.out.println("端口打开成功");
  72. } catch (final IOException e1) {
  73. e1.printStackTrace();
  74. }
  75. }
  76. public void send(byte[] out) {
  77. if (out == null || out.length < 1) {
  78. return;
  79. }
  80. synchronized (sendBuf) {
  81. sendBuf.clear();
  82. sendBuf.put(out);
  83. sendBuf.flip();
  84. }
  85. // 发送出去
  86. try {
  87. write();
  88. isSended=true;
  89. } catch (final IOException e) {
  90. e.printStackTrace();
  91. }
  92. }
  93. public void write() throws IOException {
  94. if (isConnected()) {
  95. try {
  96. socketChannel.write(sendBuf);
  97. } catch (final IOException e) {
  98. }
  99. } else {
  100. System.out.println("通道为空或者没有连接上");
  101. }
  102. }
  103. public byte[] recieve() {
  104. if (isConnected()) {
  105. try {
  106. int len = 0;
  107. int readBytes = 0;
  108. synchronized (receiveBuf) {
  109. receiveBuf.clear();
  110. try {
  111. while ((len = socketChannel.read(receiveBuf)) > 0) {
  112. readBytes += len;
  113. }
  114. } finally {
  115. receiveBuf.flip();
  116. }
  117. if (readBytes > 0) {
  118. final byte[] tmp = new byte[readBytes];
  119. receiveBuf.get(tmp);
  120. return tmp;
  121. } else {
  122. System.out.println("接收到数据为空,重新启动连接");
  123. return null;
  124. }
  125. }
  126. } catch (final IOException e) {
  127. System.out.println("接收消息错误:");
  128. }
  129. } else {
  130. System.out.println("端口没有连接");
  131. }
  132. return null;
  133. }
  134. public boolean isConnected() {
  135. return socketChannel != null && socketChannel.isConnected();
  136. }
  137. private void select() {
  138. int n = 0;
  139. try {
  140. if (selector == null) {
  141. return;
  142. }
  143. n = selector.select(1000);
  144. } catch (final Exception e) {
  145. e.printStackTrace();
  146. }
  147. // 如果select返回大于0,处理事件
  148. if (n > 0) {
  149. for (final Iterator<SelectionKey> i = selector.selectedKeys()
  150. .iterator(); i.hasNext();) {
  151. // 得到下一个Key
  152. final SelectionKey sk = i.next();
  153. i.remove();
  154. // 检查其是否还有效
  155. if (!sk.isValid()) {
  156. continue;
  157. }
  158. // 处理事件
  159. final IEvent handler = (IEvent) sk.attachment();
  160. try {
  161. if (sk.isConnectable()) {
  162. handler.connect(sk);
  163. } else if (sk.isReadable()) {
  164. handler.read(sk);
  165. } else {
  166. // System.err.println("Ooops");
  167. }
  168. } catch (final Exception e) {
  169. handler.error(e);
  170. sk.cancel();
  171. }
  172. }
  173. }
  174. }
  175. public void shutdown() {
  176. if (isConnected()) {
  177. try {
  178. socketChannel.close();
  179. System.out.println("端口关闭成功");
  180. } catch (final IOException e) {
  181. System.out.println("端口关闭错误:");
  182. } finally {
  183. socketChannel = null;
  184. }
  185. } else {
  186. System.out.println("通道为空或者没有连接");
  187. }
  188. }
  189. @Override
  190. public void run() {
  191. // 启动主循环流程
  192. while (!shutdown.get()) {
  193. try {
  194. if (isConnected()&&(!isSended)) {
  195. switch (sysStatus) {
  196. case init:
  197. doOption();
  198. break;
  199. case options:
  200. doDescribe();
  201. break;
  202. case describe:
  203. doSetup();
  204. break;
  205. case setup:
  206. if(sessionid==null&&sessionid.length()>0){
  207. System.out.println("setup还没有正常返回");
  208. }else{
  209. doPlay();
  210. }
  211. break;
  212. case play:
  213. doPause();
  214. break;
  215. case pause:
  216. doTeardown();
  217. break;
  218. default:
  219. break;
  220. }
  221. }
  222. // do select
  223. select();
  224. try {
  225. Thread.sleep(1000);
  226. } catch (final Exception e) {
  227. }
  228. } catch (final Exception e) {
  229. e.printStackTrace();
  230. }
  231. }
  232. shutdown();
  233. }
  234. public void connect(SelectionKey key) throws IOException {
  235. if (isConnected()) {
  236. return;
  237. }
  238. // 完成SocketChannel的连接
  239. socketChannel.finishConnect();
  240. while (!socketChannel.isConnected()) {
  241. try {
  242. Thread.sleep(300);
  243. } catch (final InterruptedException e) {
  244. e.printStackTrace();
  245. }
  246. socketChannel.finishConnect();
  247. }
  248. }
  249. public void error(Exception e) {
  250. e.printStackTrace();
  251. }
  252. public void read(SelectionKey key) throws IOException {
  253. // 接收消息
  254. final byte[] msg = recieve();
  255. if (msg != null) {
  256. handle(msg);
  257. } else {
  258. key.cancel();
  259. }
  260. }
  261. private void handle(byte[] msg) {
  262. String tmp = new String(msg);
  263. System.out.println("返回内容:");
  264. System.out.println(tmp);
  265. if (tmp.startsWith(RTSP_OK)) {
  266. switch (sysStatus) {
  267. case init:
  268. sysStatus = Status.options;
  269. break;
  270. case options:
  271. sysStatus = Status.describe;
  272. trackInfo=tmp.substring(tmp.indexOf("trackID"));
  273. break;
  274. case describe:
  275. sessionid = tmp.substring(tmp.indexOf("Session: ") + 9, tmp
  276. .indexOf("Date:"));
  277. if(sessionid!=null&&sessionid.length()>0){
  278. sysStatus = Status.setup;
  279. }
  280. break;
  281. case setup:
  282. sysStatus = Status.play;
  283. break;
  284. case play:
  285. sysStatus = Status.pause;
  286. break;
  287. case pause:
  288. sysStatus = Status.teardown;
  289. shutdown.set(true);
  290. break;
  291. case teardown:
  292. sysStatus = Status.init;
  293. break;
  294. default:
  295. break;
  296. }
  297. isSended=false;
  298. } else {
  299. System.out.println("返回错误:" + tmp);
  300. }
  301. }
  302. private void doTeardown() {
  303. StringBuilder sb = new StringBuilder();
  304. sb.append("TEARDOWN ");
  305. sb.append(this.address);
  306. sb.append("/");
  307. sb.append(VERSION);
  308. sb.append("Cseq: ");
  309. sb.append(seq++);
  310. sb.append("/r/n");
  311. sb.append("User-Agent: RealMedia Player HelixDNAClient/10.0.0.11279 (win32)/r/n");
  312. sb.append("Session: ");
  313. sb.append(sessionid);
  314. sb.append("/r/n");
  315. send(sb.toString().getBytes());
  316. System.out.println(sb.toString());
  317. }
  318. private void doPlay() {
  319. StringBuilder sb = new StringBuilder();
  320. sb.append("PLAY ");
  321. sb.append(this.address);
  322. sb.append(VERSION);
  323. sb.append("Session: ");
  324. sb.append(sessionid);
  325. sb.append("Cseq: ");
  326. sb.append(seq++);
  327. sb.append("/r/n");
  328. sb.append("/r/n");
  329. System.out.println(sb.toString());
  330. send(sb.toString().getBytes());
  331. }
  332. private void doSetup() {
  333. StringBuilder sb = new StringBuilder();
  334. sb.append("SETUP ");
  335. sb.append(this.address);
  336. sb.append("/");
  337. sb.append(trackInfo);
  338. sb.append(VERSION);
  339. sb.append("Cseq: ");
  340. sb.append(seq++);
  341. sb.append("/r/n");
  342. sb.append("Transport: RTP/AVP;UNICAST;client_port=16264-16265;mode=play/r/n");
  343. sb.append("/r/n");
  344. System.out.println(sb.toString());
  345. send(sb.toString().getBytes());
  346. }
  347. private void doOption() {
  348. StringBuilder sb = new StringBuilder();
  349. sb.append("OPTIONS ");
  350. sb.append(this.address.substring(0, address.lastIndexOf("/")));
  351. sb.append(VERSION);
  352. sb.append("Cseq: ");
  353. sb.append(seq++);
  354. sb.append("/r/n");
  355. sb.append("/r/n");
  356. System.out.println(sb.toString());
  357. send(sb.toString().getBytes());
  358. }
  359. private void doDescribe() {
  360. StringBuilder sb = new StringBuilder();
  361. sb.append("DESCRIBE ");
  362. sb.append(this.address);
  363. sb.append(VERSION);
  364. sb.append("Cseq: ");
  365. sb.append(seq++);
  366. sb.append("/r/n");
  367. sb.append("/r/n");
  368. System.out.println(sb.toString());
  369. send(sb.toString().getBytes());
  370. }
  371. private void doPause() {
  372. StringBuilder sb = new StringBuilder();
  373. sb.append("PAUSE ");
  374. sb.append(this.address);
  375. sb.append("/");
  376. sb.append(VERSION);
  377. sb.append("Cseq: ");
  378. sb.append(seq++);
  379. sb.append("/r/n");
  380. sb.append("Session: ");
  381. sb.append(sessionid);
  382. sb.append("/r/n");
  383. send(sb.toString().getBytes());
  384. System.out.println(sb.toString());
  385. }
  386. public static void main(String[] args) {
  387. try {
  388. // RTSPClient(InetSocketAddress remoteAddress,
  389. // InetSocketAddress localAddress, String address)
  390. RTSPClient client = new RTSPClient(
  391. new InetSocketAddress("218.207.101.236", 554),
  392. new InetSocketAddress("192.168.2.28", 0),
  393. "rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp");
  394. client.start();
  395. } catch (Exception e) {
  396. e.printStackTrace();
  397. }
  398. }
  399. }

其中:rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp为我在网上找到的一个rtsp的sdp地址,读者可自行更换,RTSP的默认端口为554.
3.3  运行结果
       运行RTSPClient.java,运行结果如下所示:

  1. 端口打开成功
  2. OPTIONS rtsp://218.207.101.236:554/mobile/3/67A451E937422331 RTSP/1.0
  3. Cseq: 1
  4. 返回内容:
  5. RTSP/1.0 200 OK
  6. Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
  7. Cseq: 1
  8. Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, OPTIONS, ANNOUNCE, RECORD
  9. DESCRIBE rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0
  10. Cseq: 2
  11. 返回内容:
  12. RTSP/1.0 200 OK
  13. Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
  14. Cseq: 2
  15. Content-length: 421
  16. Date: Mon, 03 Aug 2009 08:50:36 GMT
  17. Expires: Mon, 03 Aug 2009 08:50:36 GMT
  18. Content-Type: application/sdp
  19. x-Accept-Retransmit: our-retransmit
  20. x-Accept-Dynamic-Rate: 1
  21. Content-Base: rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/
  22. v=0
  23. o=MediaBox 127992 137813 IN IP4 0.0.0.0
  24. s=RTSP Session
  25. i=Starv Box Live Cast
  26. c=IN IP4 218.207.101.236
  27. t=0 0
  28. a=range:npt=now-
  29. a=control:*
  30. m=video 0 RTP/AVP 96
  31. b=AS:20
  32. a=rtpmap:96 MP4V-ES/1000
  33. a=fmtp:96 profile-level-id=8; config=000001b008000001b5090000010000000120008440fa282c2090a31f; decode_buf=12586
  34. a=range:npt=now-
  35. a=framerate:5
  36. a=framesize:96 176-144
  37. a=cliprect:0,0,144,176
  38. a=control:trackID=1
  39. SETUP rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1
  40. RTSP/1.0
  41. Cseq: 3
  42. Transport: RTP/AVP;UNICAST;client_port=16264-16265;mode=play
  43. 返回内容:
  44. RTSP/1.0 200 OK
  45. Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
  46. Cseq: 3
  47. Session: 15470472221769
  48. Date: Mon, 03 Aug 2009 08:50:36 GMT
  49. Expires: Mon, 03 Aug 2009 08:50:36 GMT
  50. Transport: RTP/AVP;UNICAST;mode=play;client_port=16264-16265;server_port=20080-20081
  51. PLAY rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0
  52. Session: 15470472221769
  53. Cseq: 4
  54. 返回内容:
  55. RTSP/1.0 200 OK
  56. Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
  57. Cseq: 4
  58. Session: 15470472221769
  59. RTP-Info: url=rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1;seq=0;rtptime=0
  60. PAUSE rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ RTSP/1.0
  61. Cseq: 5
  62. Session: 15470472221769
  63. 返回内容:
  64. RTSP/1.0 200 OK
  65. Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
  66. Cseq: 5
  67. Session: 15470472221769
  68. TEARDOWN rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ RTSP/1.0
  69. Cseq: 6
  70. User-Agent: RealMedia Player HelixDNAClient/10.0.0.11279 (win32)
  71. Session: 15470472221769
  72. 返回内容:
  73. RTSP/1.0 200 OK
  74. Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
  75. Cseq: 6
  76. Session: 15470472221769
  77. Connection: Close
  78. 端口关闭成功

对照运行结果,读者可以熟悉RTSP的常用命令.

RTSP协议详解的更多相关文章

  1. (转)RTSP协议详解

    转自:https://www.cnblogs.com/lidabo/p/6553212.html RTSP简介     RTSP(Real Time Streaming Protocol)是由Real ...

  2. Httpd服务进阶知识-HTTP协议详解

    Httpd服务进阶知识-HTTP协议详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.WEB开发概述 1>.C/S编程 CS即客户端.服务器编程. 客户端.服务端之间需 ...

  3. HTTP协议详解(转)

    转自:http://blog.csdn.net/gueter/archive/2007/03/08/1524447.aspx Author :Jeffrey 引言 HTTP是一个属于应用层的面向对象的 ...

  4. HTTP协议详解

    Author :Jeffrey 引言 HTTP 是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和 扩展. ...

  5. 动态选路、RIP协议&&OSPF协议详解

    动态选路.RIP协议&&OSPF协议详解 概念 当相邻路由器之间进行通信,以告知对方每个路由器当前所连接的网络,这时就出现了动态选路.路由器之间必须采用选路协议进行通信,这样的选路协议 ...

  6. ASP.NET知识总结(3.HTTP协议详解)

    引言 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1. ...

  7. 接口测试之HTTP协议详解

    引言 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1. ...

  8. 计算机网络(12)-----HTTP协议详解

    HTTP协议详解 http请求 http请求由三部分组成,分别是:请求行.消息报头.请求正文 (1)请求行 请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,格式如下:Metho ...

  9. OSPF协议详解

    CCNP OSPF协议详解 2010-02-24 20:30:22 标签:CCNP 职场 OSPF 休闲 OSPF(Open Shortest Path Fitst,ospf)开放最短路径优先协议,是 ...

随机推荐

  1. BZOJ3821 : 玄学

    对操作建立线段树,每个节点维护一个有序的操作表,表示用$[l,r]$的操作在每段区间上的作用效果. 对于一个线段树节点,合并左右儿子信息只在该区间刚刚被填满时进行,利用归并排序,时间复杂度为$O(n\ ...

  2. 关于Web Worker你必须知道的7件事

    介绍 通过使用Web Worker, 我们可以在浏览器后台运行Javascript, 而不占用浏览器自身线程.Web Worker可以提高应用的总体性能,并且提升用户体验.如果你想在自己的Web应用中 ...

  3. 动态树之link-cut tree

    说好的专题... lct的一些概念看论文 杨哲<QTREE解法的一些研究> 简单易懂. 首先不要把lct想象得很难,其实很水的.lct就是很多splay树维护的树... lct的acces ...

  4. 免杀ASP一句话

    <% wei="日日日)""wei""(tseuqer lave 日" execute(UnEncode(wei)) function ...

  5. PHPExcel 是用来操作Office Excel 文档的一个PHP类库

    PHPExcel 是用来操作Office Excel 文档的一个PHP类库,它基于微软的OpenXML标准和PHP语言.可以使用它来读取.写入不同格式的电子表格,如 Excel (BIFF) .xls ...

  6. Servlet 编程 请求的转发

    在上篇的基础上,修改servlet *转发只能在同一应用内转发. 将forward 地址改为:youku.com  不能访问 重定向是可以访问外部应用的

  7. HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  8. Maven学习记录

    一.简单介绍 Maven 是一个项目构建和管理自动化工具,通过它可以便捷的管理项目的生命周期,包括项目的jar包依赖,开发,测试,发布,打包等. 二.基本概念 2.1 Pom - 项目对象模型 全称( ...

  9. portable runtime

    APR The mission of the Apache Portable Runtime (APR) project is to create and maintain software libr ...

  10. ZOJ 2974 矩阵快速幂

    题意 给出n个杯子与初始其中有多少水 “同时”进行如下指令 将其中的水同时分入所指定的杯子 进行x次后 输出杯子剩余水量 队友想出应该是一道快速幂 但并不是过去的用初始杯子的水组成的矩阵乘某个矩阵 可 ...