`
shinfocom
  • 浏览: 1181473 次
文章分类
社区版块
存档分类
最新评论

rtsp网络协议的java实现

 
阅读更多

一.参考资料
1. 《RTSP简单命令》:http://blog.csdn.net/feidragon319/archive/2007/08/14/1742357.aspx
2.http://bbs.21eic.com/dispbbs.asp?boardid=15&Id=22948
3. 《RTSP客户端的Java实现》:http://hi.baidu.com/ssyuan/blog/item/566df6defac1dc5094ee37eb.html

二. RTSP的常用命令与解释
其中C是客户端,S是服务端。
2.1 OPTIONS
C->S: OPTION request //询问S有哪些方法可用
S->C: OPTION response //S回应信息中包括提供的所有可用方法
使用举例:
客户端到服务端:

Java代码
  1. OPTIONSrtsp://218.207.101.236:554/mobile/3/67A451E937422331RTSP/1.0
  2. Cseq:1

服务端对OPTIONS的回应:

Java代码
  1. RTSP/1.0200OK
  2. Server:PVSS/1.4.8(Build/20090111;Platform/Win32;Release/StarValley;)
  3. Cseq:1
  4. Public:DESCRIBE,SETUP,TEARDOWN,PLAY,PAUSE,OPTIONS,ANNOUNCE,RECORD

2.2 DESCRIBE

C->S: DESCRIBE request //要求得到S提供的媒体初始化描述信息
S->C: DESCRIBE response //S回应媒体初始化描述信息,主要是sdp

使用举例:
客户端到服务端:

Java代码
  1. DESCRIBE
Java代码
  1. rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdpRTSP/1.0
  2. Cseq:2

服务端对OPTIONS的回应:

Java代码
  1. RTSP/1.0200OK
  2. Server:PVSS/1.4.8(Build/20090111;Platform/Win32;Release/StarValley;)
  3. Cseq:2
  4. Content-length:421
  5. Date:Mon,03Aug200908:21:33GMT
  6. Expires:Mon,03Aug200908:21:33GMT
  7. Content-Type:application/sdp
  8. x-Accept-Retransmit:our-retransmit
  9. x-Accept-Dynamic-Rate:1
  10. Content-Base:rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/
  11. v=0
  12. o=MediaBox127992137813INIP40.0.0.0
  13. s=RTSPSession
  14. i=StarvBoxLiveCast
  15. c=INIP4218.207.101.236
  16. t=00
  17. a=range:npt=now-
  18. a=control:*
  19. m=video0RTP/AVP96
  20. b=AS:20
  21. a=rtpmap:96MP4V-ES/1000
  22. a=fmtp:96profile-level-id=8;config=000001b008000001b5090000010000000120008440fa282c2090a31f;decode_buf=12586
  23. a=range:npt=now-
  24. a=framerate:5
  25. a=framesize:96176-144
  26. a=cliprect:0,0,144,176
  27. a=control:trackID=1

2.3 SETUP
C->S: SETUP request //设置会话的属性,以及传输模式,提醒S建立会话
S->C: SETUP response //S建立会话,返回会话标识符,以及会话相关信息
客户端到服务端的请求举例:

Java代码
  1. SETUPrtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1
  2. RTSP/1.0
  3. Cseq:3
  4. Transport:RTP/AVP;UNICAST;client_port=16264-16265;mode=play

服务端对客户端的回应举例:

Java代码
  1. RTSP/1.0200OK
  2. Server:PVSS/1.4.8(Build/20090111;Platform/Win32;Release/StarValley;)
  3. Cseq:3
  4. Session:26633092229589
  5. Date:Mon,03Aug200908:21:33GMT
  6. Expires:Mon,03Aug200908:21:33GMT
  7. Transport:RTP/AVP;UNICAST;mode=play;client_port=16264-16265;server_port=20026-20027

2.4 PLAY
C->S: PLAY request //C请求播放
S->C: PLAY response //S回应该请求的信息
客户端到服务端的请求举例:

Java代码
  1. PLAYrtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdpRTSP/1.0
  2. Session:26633092229589
  3. Cseq:4

服务端对客户端的回应举例:

Java代码
  1. RTSP/1.0200OK
  2. Server:PVSS/1.4.8(Build/20090111;Platform/Win32;Release/StarValley;)
  3. Cseq:4
  4. Session:26633092229589
  5. RTP-Info:url=rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1;seq=0;rtptime=0

2.5 PAUSE
C->S: PAUSE request //C请求暂停播放
S->C:PAUSE response //S回应该请求的信息
客户端到服务端的请求举例:

Java代码
  1. PAUSErtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/RTSP/1.0
  2. Cseq:5
  3. Session:26633092229589

服务端对客户端的回应举例:

Java代码
  1. RTSP/1.0200OK
  2. Server:PVSS/1.4.8(Build/20090111;Platform/Win32;Release/StarValley;)
  3. Cseq:5
  4. Session:26633092229589

2.6 TEARDOWN
C->S: TEARDOWN request //C请求关闭会话
S->C: TEARDOWN response //S回应该请求
客户端到服务端的请求举例:

Java代码
  1. TEARDOWNrtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/RTSP/1.0
  2. Cseq:6
  3. User-Agent:RealMediaPlayerHelixDNAClient/10.0.0.11279(win32)
  4. Session:26633092229589

服务端对客户端的回应举例:

Java代码
  1. RTSP/1.0200OK
  2. Server:PVSS/1.4.8(Build/20090111;Platform/Win32;Release/StarValley;)
  3. Cseq:6
  4. Session:26633092229589
  5. Connection:Close

三. RTSP客户端的Java实现
3.1接口IEvent.java

接口IEvent.java的代码如下:

Java代码
  1. packagecom.amigo.rtsp;
  2. importjava.io.IOException;
  3. importjava.nio.channels.SelectionKey;
  4. /***//**
  5. *IEvent.java网络事件处理器,当Selector可以进行操作时,调用这个接口中的方法.
  6. *2007-3-22下午03:35:51
  7. *@authorsycheng
  8. *@version1.0
  9. */
  10. publicinterfaceIEvent{
  11. /***//**
  12. *当channel得到connect事件时调用这个方法.
  13. *@paramkey
  14. *@throwsIOException
  15. */
  16. voidconnect(SelectionKeykey)throwsIOException;
  17. /***//**
  18. *当channel可读时调用这个方法.
  19. *@paramkey
  20. *@throwsIOException
  21. */
  22. voidread(SelectionKeykey)throwsIOException;
  23. /***//**
  24. *当channel可写时调用这个方法.
  25. *@throwsIOException
  26. */
  27. voidwrite()throwsIOException;
  28. /***//**
  29. *当channel发生错误时调用.
  30. *@parame
  31. */
  32. voiderror(Exceptione);
  33. }

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

Java代码
  1. packagecom.amigo.rtsp;
  2. importjava.io.IOException;
  3. importjava.net.InetSocketAddress;
  4. importjava.nio.ByteBuffer;
  5. importjava.nio.channels.SelectionKey;
  6. importjava.nio.channels.Selector;
  7. importjava.nio.channels.SocketChannel;
  8. importjava.util.Iterator;
  9. importjava.util.concurrent.atomic.AtomicBoolean;
  10. publicclassRTSPClientextendsThreadimplementsIEvent{
  11. privatestaticfinalStringVERSION="RTSP/1.0/r/n";
  12. privatestaticfinalStringRTSP_OK="RTSP/1.0200OK";
  13. /***//**远程地址*/
  14. privatefinalInetSocketAddressremoteAddress;
  15. /***//***本地地址*/
  16. privatefinalInetSocketAddresslocalAddress;
  17. /***//***连接通道*/
  18. privateSocketChannelsocketChannel;
  19. /***//**发送缓冲区*/
  20. privatefinalByteBuffersendBuf;
  21. /***//**接收缓冲区*/
  22. privatefinalByteBufferreceiveBuf;
  23. privatestaticfinalintBUFFER_SIZE=8192;
  24. /***//**端口选择器*/
  25. privateSelectorselector;
  26. privateStringaddress;
  27. privateStatussysStatus;
  28. privateStringsessionid;
  29. /***//**线程是否结束的标志*/
  30. privateAtomicBooleanshutdown;
  31. privateintseq=1;
  32. privatebooleanisSended;
  33. privateStringtrackInfo;
  34. privateenumStatus{
  35. init,options,describe,setup,play,pause,teardown
  36. }
  37. publicRTSPClient(InetSocketAddressremoteAddress,
  38. InetSocketAddresslocalAddress,Stringaddress){
  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(finalIOExceptione){
  50. e.printStackTrace();
  51. }
  52. }
  53. startup();
  54. sysStatus=Status.init;
  55. shutdown=newAtomicBoolean(false);
  56. isSended=false;
  57. }
  58. publicvoidstartup(){
  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(finalIOExceptione1){
  73. e1.printStackTrace();
  74. }
  75. }
  76. publicvoidsend(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(finalIOExceptione){
  90. e.printStackTrace();
  91. }
  92. }
  93. publicvoidwrite()throwsIOException{
  94. if(isConnected()){
  95. try{
  96. socketChannel.write(sendBuf);
  97. }catch(finalIOExceptione){
  98. }
  99. }else{
  100. System.out.println("通道为空或者没有连接上");
  101. }
  102. }
  103. publicbyte[]recieve(){
  104. if(isConnected()){
  105. try{
  106. intlen=0;
  107. intreadBytes=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. finalbyte[]tmp=newbyte[readBytes];
  119. receiveBuf.get(tmp);
  120. returntmp;
  121. }else{
  122. System.out.println("接收到数据为空,重新启动连接");
  123. returnnull;
  124. }
  125. }
  126. }catch(finalIOExceptione){
  127. System.out.println("接收消息错误:");
  128. }
  129. }else{
  130. System.out.println("端口没有连接");
  131. }
  132. returnnull;
  133. }
  134. publicbooleanisConnected(){
  135. returnsocketChannel!=null&&socketChannel.isConnected();
  136. }
  137. privatevoidselect(){
  138. intn=0;
  139. try{
  140. if(selector==null){
  141. return;
  142. }
  143. n=selector.select(1000);
  144. }catch(finalExceptione){
  145. e.printStackTrace();
  146. }
  147. //如果select返回大于0,处理事件
  148. if(n>0){
  149. for(finalIterator<SelectionKey>i=selector.selectedKeys()
  150. .iterator();i.hasNext();){
  151. //得到下一个Key
  152. finalSelectionKeysk=i.next();
  153. i.remove();
  154. //检查其是否还有效
  155. if(!sk.isValid()){
  156. continue;
  157. }
  158. //处理事件
  159. finalIEventhandler=(IEvent)sk.attachment();
  160. try{
  161. if(sk.isConnectable()){
  162. handler.connect(sk);
  163. }elseif(sk.isReadable()){
  164. handler.read(sk);
  165. }else{
  166. //System.err.println("Ooops");
  167. }
  168. }catch(finalExceptione){
  169. handler.error(e);
  170. sk.cancel();
  171. }
  172. }
  173. }
  174. }
  175. publicvoidshutdown(){
  176. if(isConnected()){
  177. try{
  178. socketChannel.close();
  179. System.out.println("端口关闭成功");
  180. }catch(finalIOExceptione){
  181. System.out.println("端口关闭错误:");
  182. }finally{
  183. socketChannel=null;
  184. }
  185. }else{
  186. System.out.println("通道为空或者没有连接");
  187. }
  188. }
  189. @Override
  190. publicvoidrun(){
  191. //启动主循环流程
  192. while(!shutdown.get()){
  193. try{
  194. if(isConnected()&&(!isSended)){
  195. switch(sysStatus){
  196. caseinit:
  197. doOption();
  198. break;
  199. caseoptions:
  200. doDescribe();
  201. break;
  202. casedescribe:
  203. doSetup();
  204. break;
  205. casesetup:
  206. if(sessionid==null&&sessionid.length()>0){
  207. System.out.println("setup还没有正常返回");
  208. }else{
  209. doPlay();
  210. }
  211. break;
  212. caseplay:
  213. doPause();
  214. break;
  215. casepause:
  216. doTeardown();
  217. break;
  218. default:
  219. break;
  220. }
  221. }
  222. //doselect
  223. select();
  224. try{
  225. Thread.sleep(1000);
  226. }catch(finalExceptione){
  227. }
  228. }catch(finalExceptione){
  229. e.printStackTrace();
  230. }
  231. }
  232. shutdown();
  233. }
  234. publicvoidconnect(SelectionKeykey)throwsIOException{
  235. if(isConnected()){
  236. return;
  237. }
  238. //完成SocketChannel的连接
  239. socketChannel.finishConnect();
  240. while(!socketChannel.isConnected()){
  241. try{
  242. Thread.sleep(300);
  243. }catch(finalInterruptedExceptione){
  244. e.printStackTrace();
  245. }
  246. socketChannel.finishConnect();
  247. }
  248. }
  249. publicvoiderror(Exceptione){
  250. e.printStackTrace();
  251. }
  252. publicvoidread(SelectionKeykey)throwsIOException{
  253. //接收消息
  254. finalbyte[]msg=recieve();
  255. if(msg!=null){
  256. handle(msg);
  257. }else{
  258. key.cancel();
  259. }
  260. }
  261. privatevoidhandle(byte[]msg){
  262. Stringtmp=newString(msg);
  263. System.out.println("返回内容:");
  264. System.out.println(tmp);
  265. if(tmp.startsWith(RTSP_OK)){
  266. switch(sysStatus){
  267. caseinit:
  268. sysStatus=Status.options;
  269. break;
  270. caseoptions:
  271. sysStatus=Status.describe;
  272. trackInfo=tmp.substring(tmp.indexOf("trackID"));
  273. break;
  274. casedescribe:
  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. casesetup:
  282. sysStatus=Status.play;
  283. break;
  284. caseplay:
  285. sysStatus=Status.pause;
  286. break;
  287. casepause:
  288. sysStatus=Status.teardown;
  289. shutdown.set(true);
  290. break;
  291. caseteardown:
  292. sysStatus=Status.init;
  293. break;
  294. default:
  295. break;
  296. }
  297. isSended=false;
  298. }else{
  299. System.out.println("返回错误:"+tmp);
  300. }
  301. }
  302. privatevoiddoTeardown(){
  303. StringBuildersb=newStringBuilder();
  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:RealMediaPlayerHelixDNAClient/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. privatevoiddoPlay(){
  319. StringBuildersb=newStringBuilder();
  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. privatevoiddoSetup(){
  333. StringBuildersb=newStringBuilder();
  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. privatevoiddoOption(){
  348. StringBuildersb=newStringBuilder();
  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. privatevoiddoDescribe(){
  360. StringBuildersb=newStringBuilder();
  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. privatevoiddoPause(){
  372. StringBuildersb=newStringBuilder();
  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. publicstaticvoidmain(String[]args){
  387. try{
  388. //RTSPClient(InetSocketAddressremoteAddress,
  389. //InetSocketAddresslocalAddress,Stringaddress)
  390. RTSPClientclient=newRTSPClient(
  391. newInetSocketAddress("218.207.101.236",554),
  392. newInetSocketAddress("192.168.2.28",0),
  393. "rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp");
  394. client.start();
  395. }catch(Exceptione){
  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,运行结果如下所示:

Java代码
  1. 端口打开成功
  2. OPTIONSrtsp://218.207.101.236:554/mobile/3/67A451E937422331RTSP/1.0
  3. Cseq:1
  4. 返回内容:
  5. RTSP/1.0200OK
  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. DESCRIBErtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdpRTSP/1.0
  10. Cseq:2
  11. 返回内容:
  12. RTSP/1.0200OK
  13. Server:PVSS/1.4.8(Build/20090111;Platform/Win32;Release/StarValley;)
  14. Cseq:2
  15. Content-length:421
  16. Date:Mon,03Aug200908:50:36GMT
  17. Expires:Mon,03Aug200908:50:36GMT
  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=MediaBox127992137813INIP40.0.0.0
  24. s=RTSPSession
  25. i=StarvBoxLiveCast
  26. c=INIP4218.207.101.236
  27. t=00
  28. a=range:npt=now-
  29. a=control:*
  30. m=video0RTP/AVP96
  31. b=AS:20
  32. a=rtpmap:96MP4V-ES/1000
  33. a=fmtp:96profile-level-id=8;config=000001b008000001b5090000010000000120008440fa282c2090a31f;decode_buf=12586
  34. a=range:npt=now-
  35. a=framerate:5
  36. a=framesize:96176-144
  37. a=cliprect:0,0,144,176
  38. a=control:trackID=1
  39. SETUPrtsp://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.0200OK
  45. Server:PVSS/1.4.8(Build/20090111;Platform/Win32;Release/StarValley;)
  46. Cseq:3
  47. Session:15470472221769
  48. Date:Mon,03Aug200908:50:36GMT
  49. Expires:Mon,03Aug200908:50:36GMT
  50. Transport:RTP/AVP;UNICAST;mode=play;client_port=16264-16265;server_port=20080-20081
  51. PLAYrtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdpRTSP/1.0
  52. Session:15470472221769
  53. Cseq:4
  54. 返回内容:
  55. RTSP/1.0200OK
  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. PAUSErtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/RTSP/1.0
  61. Cseq:5
  62. Session:15470472221769
  63. 返回内容:
  64. RTSP/1.0200OK
  65. Server:PVSS/1.4.8(Build/20090111;Platform/Win32;Release/StarValley;)
  66. Cseq:5
  67. Session:15470472221769
  68. TEARDOWNrtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/RTSP/1.0
  69. Cseq:6
  70. User-Agent:RealMediaPlayerHelixDNAClient/10.0.0.11279(win32)
  71. Session:15470472221769
  72. 返回内容:
  73. RTSP/1.0200OK
  74. Server:PVSS/1.4.8(Build/20090111;Platform/Win32;Release/StarValley;)
  75. Cseq:6
  76. Session:15470472221769
  77. Connection:Close
  78. 端口关闭成功

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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics