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. it's hard to say

    Ew,it's hard to begin.In fact I don't know what to say either.So here is a sad story.First of all ,m ...

  2. css expression

    概述 css expression(css表达式)又称Dynamic properties(动态属性)是早期微软DHTML的产物,以其可以在Css中定义表达式(公式)来达到建立元素间属性之间的联系等作 ...

  3. COJ1013 : WZJ的数据结构(十三)

    这道题有这样一个解法: 首先把边依次加到图中,若当前这条边与图中的边形成了环,那么把这个环中最早加进来的边弹出去并将每条边把哪条边弹了出去记录下来:ntr[i] = j,特别地,要是没有弹出边,ntr ...

  4. CentOS Git的还原和操作

    $ git log --graph --oneline $ git reset --hard 版本号 用 reflog 挽救错误的重置 [jackluo@localhost demo]$ git re ...

  5. iOS移动开发周报-第21期

    iOS移动开发周报-第21期 [摘要]:本期iOS移动开发周报带来如下内容:苹果iCloud中国数据转存中国电信,Swift Operators,100 个 Swift 必备 tips,FLEXLoa ...

  6. hdu Can you solve this equation?

    本题是一道二分的题,核心就是mi的大小,即精度的取值.因为原函数是一个单调递增的函数,所以可以确定y的取值范围,并且在范围内的每一个y的值,一定至少存在一个x与其对应.刚开始我将取二分这个环节用一个函 ...

  7. 按月将Windows日志导出至CSV文件

    # 这个月的第一天 #..........................................到这里之前是取当年第一天 #(Get-Date 0).AddYears((Get-Date). ...

  8. 分布式架构高可用架构篇_04_Keepalived+Nginx实现高可用Web负载均衡

    参考: 龙果学院http://www.roncoo.com/share.html?hamc=hLPG8QsaaWVOl2Z76wpJHp3JBbZZF%2Bywm5vEfPp9LbLkAjAnB%2B ...

  9. WEB项目web.xml文件中classpath: 跟classpath*:使用的区别

    引用一篇很不错的文章:http://blog.csdn.net/wxwzy738/article/details/16983935 首先 classpath是指 WEB-INF文件夹下的classes ...

  10. Sublime Text初识

    一 基础安装1. 安装Package Control使用快捷键ctrl+`,调出输出窗口, 然后输入官网提供的代码, 获取代码地址:https://packagecontrol.io/installa ...