zoukankan      html  css  js  c++  java
  • 流媒体技术之RTSP

    流媒体技术之RTSP

    标签: RTSP技术移动流媒体
     分类:

         最近对于流媒体技术比较感兴趣,虽然读书的时候学过相关方面的基础知识,但是大学上课,你懂得,一方面理论与实际脱节很严重,另一方面考试完全就是突击。学了和没学一样。好了,吐槽结束,书归正文。

        研究流媒体技术的前提是先明白三个协议,RTSP,RTCP和RTP。关于这三种协议具体的定义百度上可以说是一抓一大把。总的来说, RTSP控制负责控制,包括创建,播放和暂停等操作,RTCP和RTP可以认为是一种协议,最大的区别 是RTCP中没有负载(payload,也就是媒体数据流),RTP则包含了负载。RTCP主要负责传输server和client的状态,如已经接收了多少数据,时间戳是什么,而RTP主要作用就是传输流媒体数据。

        大部分对于RTSP都提到了这一个词:“RTSP是文本协议”,这句话是什么意思?通俗点说,如果你想告诉服务器你的名字,你首先构建一个类似于name="xxxxx"的字符串,然后把这个字符串转成byte[],经过SOCKET传给服务器,服务器就能够知道你的名字了。与之形成对比的是RTCP,RTCP规定了每个比特的每一位都代表什么,例如一个RTCP包的第一个比特的前两位代表版本,第三位用来填充,而第二个比特代表这次会话的序列号。坦率的说,实现RTCP协议可比RTSP烧脑多了。

       回到RTSP这个话题,RTSP协议包含以下几种操作,option,describe,setup,play,pause和teardown。option是询问服务器你能提供什么方法,describe则是获取服务器的详细信息,setup是与服务器建立连接,服务器返回一个sessionid用来之后进行鉴权,play就是通知服务器可以发数据了,pause则是通知服务器暂停发数据,teardown,挥泪告别,さようなら。

       如果你在百度上搜索过如下的关键字:RTSP  Java。你会发现有人已经实现了RTSP协议,如果你真的使用了那份代码,恭喜你,你踩到坑啦。大部分转载的人并没有对转载的内容进行验证。我被网上的这份代码坑了号就,今天刚刚出坑,特此记录。

        RTSPProtocal:RTSP协议类,主要负责创建RTSP文本

        

    [java] view plain copy
     
    1. public class RTSPProtocal {  
    2.       
    3.     public static byte[] encodeOption(String address, String VERSION, int seq) {    
    4.         StringBuilder sb = new StringBuilder();    
    5.         sb.append("OPTIONS ");    
    6.         sb.append(address.substring(0, address.lastIndexOf("/")));    
    7.         sb.append(VERSION);    
    8.         sb.append("Cseq: ");    
    9.         sb.append(seq);    
    10.         sb.append(" ");    
    11.         sb.append(" ");    
    12.         System.out.println(sb.toString());    
    13.         //send(sb.toString().getBytes());  
    14.         return sb.toString().getBytes();  
    15.     }  
    16.       
    17.     public static byte[] encodeDescribe(String address, String VERSION, int seq) {    
    18.         StringBuilder sb = new StringBuilder();    
    19.         sb.append("DESCRIBE ");    
    20.         sb.append(address);    
    21.         sb.append(VERSION);    
    22.         sb.append("Cseq: ");    
    23.         sb.append(seq);    
    24.         sb.append(" ");    
    25.         sb.append(" ");    
    26.         System.out.println(sb.toString());    
    27.         //send(sb.toString().getBytes());  
    28.         return sb.toString().getBytes();    
    29.     }  
    30.       
    31.     public static byte[] encodeSetup(String address, String VERSION, String sessionid,   
    32.                                         int portOdd, int portEven, int seq, String trackInfo) {    
    33.         StringBuilder sb = new StringBuilder();    
    34.         sb.append("SETUP ");    
    35.         sb.append(address);    
    36.         sb.append("/");    
    37.         sb.append(trackInfo);    
    38.         sb.append(VERSION);    
    39.         sb.append("Cseq: ");    
    40.         sb.append(seq++);    
    41.         sb.append(" ");  
    42.         //"50002-50003"  
    43.         sb.append("Transport: RTP/AVP;UNICAST;client_port="+portEven+"-"+portOdd+";mode=play ");    
    44.         sb.append(" ");    
    45.         System.out.println(sb.toString());    
    46.         System.out.println(sb.toString());    
    47.         //send(sb.toString().getBytes());    
    48.         return sb.toString().getBytes();  
    49.     }  
    50.       
    51.     public static byte[] encodePlay(String address, String VERSION, String sessionid, int seq) {    
    52.         StringBuilder sb = new StringBuilder();    
    53.         sb.append("PLAY ");    
    54.         sb.append(address);    
    55.         sb.append(VERSION);    
    56.         sb.append("Session: ");    
    57.         sb.append(sessionid);    
    58.         sb.append("Cseq: ");    
    59.         sb.append(seq);  
    60.         sb.append(" ");  
    61.         sb.append("Range: npt=0.000-");  
    62.         sb.append(" ");    
    63.         sb.append(" ");    
    64.         System.out.println(sb.toString());    
    65.         //send(sb.toString().getBytes());    
    66.         return sb.toString().getBytes();  
    67.     }  
    68.       
    69.     public static byte[] encodePause(String address, String VERSION, String sessionid, int seq) {    
    70.         StringBuilder sb = new StringBuilder();    
    71.         sb.append("PAUSE ");    
    72.         sb.append(address);    
    73.         sb.append("/");    
    74.         sb.append(VERSION);    
    75.         sb.append("Cseq: ");    
    76.         sb.append(seq);    
    77.         sb.append(" ");    
    78.         sb.append("Session: ");    
    79.         sb.append(sessionid);    
    80.         sb.append(" ");    
    81.         System.out.println(sb.toString());    
    82.         //send(sb.toString().getBytes());  
    83.         return sb.toString().getBytes();  
    84.     }  
    85.       
    86.     public static byte[] encodeTeardown(String address, String VERSION, String sessionid, int seq) {    
    87.         StringBuilder sb = new StringBuilder();    
    88.         sb.append("TEARDOWN ");    
    89.         sb.append(address);    
    90.         sb.append("/");    
    91.         sb.append(VERSION);    
    92.         sb.append("Cseq: ");    
    93.         sb.append(seq);    
    94.         sb.append(" ");  
    95.         sb.append("User-Agent: LibVLC/2.2.1 (LIVE555 Streaming Media v2014.07.25) ");    
    96.         sb.append("Session: ");    
    97.         sb.append(sessionid);    
    98.         sb.append(" ");  
    99.         System.out.println(sb.toString());   
    100.         return sb.toString().getBytes();  
    101.         //send(sb.toString().getBytes());    
    102.         //   
    103.     }  
    104. }  
       RTSPClient:使用RTSPProtocal中的静态方法获取字符创,拥有发送和接收数据的功能
    [java] view plain copy
     
    1. import java.io.IOException;  
    2. import java.net.InetSocketAddress;  
    3. import java.net.Socket;  
    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.HashMap;  
    9. import java.util.Map;  
    10.   
    11. public class RTSPClient {  
    12.       
    13.     private static final int BUFFER_SIZE = 8192;  
    14.       
    15.     private String localIpAddress;  
    16.     private String remoteIpAddress;  
    17.       
    18.     private int localPort;  
    19.     private int localPortOdd;  
    20.     private int localPortEven;  
    21.     private int remoteIPort;  
    22.       
    23.     private int remotePortOdd;  
    24.     private int remotePortEven;  
    25.       
    26.     private Map<Integer, ReceiveSocket> map = new HashMap<>();  
    27.       
    28.       
    29.       
    30.     public int getRemotePortOdd() {  
    31.         return remotePortOdd;  
    32.     }  
    33.     public void setRemotePortOdd(int remotePortOdd) {  
    34.         this.remotePortOdd = remotePortOdd;  
    35.     }  
    36.     public int getRemotePortEven() {  
    37.         return remotePortEven;  
    38.     }  
    39.     public void setRemotePortEven(int remotePortEven) {  
    40.         this.remotePortEven = remotePortEven;  
    41.     }  
    42.       
    43.     public void addSocket(Integer port, ReceiveSocket socket){  
    44.         map.put(port, socket);  
    45.     }  
    46.       
    47.     private String rtspAddress;  
    48.     private Socket tcpSocket;  
    49.       
    50.     private SocketChannel socketChannel;  
    51.     private Selector selector;   
    52.       
    53.     public String getLocalIpAddress() {  
    54.         return localIpAddress;  
    55.     }  
    56.     public void setLocalIpAddress(String localIpAddress) {  
    57.         this.localIpAddress = localIpAddress;  
    58.     }  
    59.     public int getLocalPort() {  
    60.         return localPort;  
    61.     }  
    62.     public void setLocalPort(int localPort) {  
    63.         this.localPort = localPort;  
    64.     }  
    65.     public int getLocalPortOdd() {  
    66.         return localPortOdd;  
    67.     }  
    68.     public void setLocalPortOdd(int localPortOdd) {  
    69.         this.localPortOdd = localPortOdd;  
    70.     }  
    71.     public int getLocalPortEven() {  
    72.         return localPortEven;  
    73.     }  
    74.     public void setLocalPortEven(int localPortEven) {  
    75.         this.localPortEven = localPortEven;  
    76.     }  
    77.     public String getRtspAddress() {  
    78.         return rtspAddress;  
    79.     }  
    80.     public void setRtspAddress(String rtspAddress) {  
    81.         this.rtspAddress = rtspAddress;  
    82.     }  
    83.     public Socket getTcpSocket() {  
    84.         return tcpSocket;  
    85.     }  
    86.     public void setTcpSocket(Socket tcpSocket) {  
    87.         this.tcpSocket = tcpSocket;  
    88.     }  
    89.       
    90.       
    91.     public String getRemoteIpAddress() {  
    92.         return remoteIpAddress;  
    93.     }  
    94.     public void setRemoteIpAddress(String remoteIpAddress) {  
    95.         this.remoteIpAddress = remoteIpAddress;  
    96.     }  
    97.     public int getRemoteIPort() {  
    98.         return remoteIPort;  
    99.     }  
    100.     public void setRemoteIPort(int remoteIPort) {  
    101.         this.remoteIPort = remoteIPort;  
    102.     }  
    103.       
    104.     public Selector getSelector() {  
    105.         return selector;  
    106.     }  
    107.     public void setSelector(Selector selector) {  
    108.         this.selector = selector;  
    109.     }  
    110.     //new InetSocketAddress(    
    111.     //remoteIp, 554),    
    112.     //new InetSocketAddress("192.168.31.106", 0),    
    113.     //"rtsp://218.204.223.237:554/live/1/66251FC11353191F/e7ooqwcfbqjoo80j.sdp"  
    114.     public void inital() throws IOException{  
    115.          socketChannel = SocketChannel.open();     
    116.          socketChannel.socket().setSoTimeout(30000);    
    117.          socketChannel.configureBlocking(false);  
    118.            
    119.          InetSocketAddress localAddress = new InetSocketAddress(this.localIpAddress, localPort);  
    120.          InetSocketAddress remoteAddress=new InetSocketAddress(this.remoteIpAddress, 554);  
    121.            
    122.          socketChannel.socket().bind(localAddress);    
    123.          if (socketChannel.connect(remoteAddress)) {    
    124.              System.out.println("开始建立连接:" + remoteAddress);    
    125.          }   
    126.            
    127.          if (selector == null) {    
    128.              // 创建新的Selector    
    129.              try {    
    130.                  selector = Selector.open();    
    131.              } catch (final IOException e) {    
    132.                  e.printStackTrace();    
    133.              }    
    134.          }  
    135.          socketChannel.register(selector, SelectionKey.OP_CONNECT    
    136.                  | SelectionKey.OP_READ | SelectionKey.OP_WRITE, this);    
    137.          System.out.println("端口打开成功");  
    138.     }  
    139.       
    140.     public void write(byte[] out) throws IOException {    
    141.         if (out == null || out.length < 1) {    
    142.             return;    
    143.         }  
    144.         System.out.println(out.toString());  
    145.         ByteBuffer sendBuf = ByteBuffer.allocateDirect(BUFFER_SIZE);  
    146.         sendBuf.clear();    
    147.         sendBuf.put(out);    
    148.         sendBuf.flip();  
    149.         if (isConnected()) {    
    150.             try {    
    151.                 socketChannel.write(sendBuf);    
    152.             } catch (final IOException e) {    
    153.             }    
    154.         } else {    
    155.             System.out.println("通道为空或者没有连接上");    
    156.         }    
    157.     }  
    158.       
    159.     public boolean isConnected() {    
    160.         return socketChannel != null && socketChannel.isConnected();    
    161.     }  
    162.       
    163.     public byte[] receive() {    
    164.         if (isConnected()) {    
    165.             try {    
    166.                 int len = 0;    
    167.                 int readBytes = 0;  
    168.                 ByteBuffer receiveBuf = ByteBuffer.allocateDirect(BUFFER_SIZE);  
    169.                 synchronized (receiveBuf) {    
    170.                     receiveBuf.clear();    
    171.                     try {    
    172.                         while ((len = socketChannel.read(receiveBuf)) > 0) {    
    173.                             readBytes += len;    
    174.                         }    
    175.                     } finally {    
    176.                         receiveBuf.flip();    
    177.                     }    
    178.                     if (readBytes > 0) {    
    179.                         final byte[] tmp = new byte[readBytes];    
    180.                         receiveBuf.get(tmp);    
    181.                         return tmp;    
    182.                     } else {    
    183.                         System.out.println("接收到数据为空,重新启动连接");    
    184.                         return null;    
    185.                     }    
    186.                 }    
    187.             } catch (final IOException e) {    
    188.                 System.out.println("接收消息错误:");    
    189.             }    
    190.         } else {    
    191.             System.out.println("端口没有连接");    
    192.         }    
    193.         return null;    
    194.     }  
    195.     /* 
    196.      * 非常重要 
    197.      * */  
    198.     public void sendBeforePlay(){  
    199.         ReceiveSocket socketEven = map.get(this.localPortEven);  
    200.         ReceiveSocket socketOdd = map.get(this.localPortOdd);  
    201.         if(socketEven == null){  
    202.             socketEven = new ReceiveSocket(this.localIpAddress,this.localPortEven);  
    203.             map.put(this.localPortEven, socketEven);  
    204.         }  
    205.         if(socketOdd == null){  
    206.             socketEven = new ReceiveSocket(this.localIpAddress, this.localPortOdd);  
    207.             map.put(this.localPortOdd, socketOdd);  
    208.         }  
    209.         byte[] bytes = new byte[1];  
    210.         bytes[0]=0;  
    211.         try {  
    212.             socketEven.send(bytes, this.remoteIpAddress, this.remotePortEven);  
    213.             socketOdd.send(bytes, this.remoteIpAddress, this.remotePortOdd);  
    214.         } catch (IOException e) {  
    215.             e.printStackTrace();  
    216.         }  
    217.         return;  
    218.     }  
    219.       
    220.     public void reConnect(SelectionKey key) throws IOException {    
    221.         if (isConnected()) {    
    222.             return;    
    223.         }    
    224.         // 完成SocketChannel的连接    
    225.         socketChannel.finishConnect();    
    226.         while (!socketChannel.isConnected()) {    
    227.             try {    
    228.                 Thread.sleep(300);    
    229.             } catch (final InterruptedException e) {    
    230.                 e.printStackTrace();    
    231.             }    
    232.             socketChannel.finishConnect();    
    233.         }    
    234.     
    235.     }  
    236. }  
       ReceiveSocket:用来接收服务器发来的RTP和RTCP协议数据,只是简单地对UDP进行了包装而已
    [java] view plain copy
     
    1. import java.io.IOException;  
    2. import java.net.DatagramPacket;  
    3. import java.net.DatagramSocket;  
    4. import java.net.InetAddress;  
    5. import java.net.InetSocketAddress;  
    6. import java.net.SocketException;  
    7. import java.net.UnknownHostException;  
    8.   
    9.   
    10. public class ReceiveSocket implements Runnable{  
    11.       
    12.     private DatagramSocket ds;  
    13.     public ReceiveSocket(String localAddress, int port){  
    14.          try {  
    15.               
    16.             InetSocketAddress addr = new InetSocketAddress("192.168.31.106", port);  
    17.             ds = new DatagramSocket(addr);//监听16264端口  
    18.         } catch (SocketException e) {  
    19.             e.printStackTrace();  
    20.         }     
    21.     }  
    22.       
    23.     @Override  
    24.     public void run() {  
    25.         // TODO Auto-generated method stub  
    26.         while(true){  
    27.             byte[] buf = new byte[20];    
    28.             DatagramPacket dp = new DatagramPacket(buf,buf.length);    
    29.             try   
    30.             {  
    31.                 ds.receive(dp);  
    32.                 String ip = dp.getAddress().getHostAddress();   //数据提取    
    33.                 String data = new String(dp.getData(),0,dp.getLength());    
    34.                 int port = dp.getPort();    
    35.                 System.out.println(data+"."+port+".."+ip);  
    36.             } catch (IOException e) {  
    37.                 // TODO Auto-generated catch block  
    38.                 e.printStackTrace();  
    39.             }     
    40.         }      
    41.     }  
    42.       
    43.     public void send(byte[] buf, String ip, int rec_port) throws IOException {  
    44.         // TODO Auto-generated method stub  
    45.         DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName(ip),rec_port);//10000为定义的端口       
    46.         ds.send(dp);    
    47.         //ds.close();      
    48.     }  
    49. }  
        PlayerClient:播放类,通过不同状态之间的相互转化完成RTSP协议的交互工作。这里有一点非常关键:请注意setup这个状态,在和服务器建立连接之后,如果直接发送PLAY请求,服务器不会向指定的端口发送RTCP数据(这个问题困扰了我一晚上)。因此在发送PLAY请求之前,client接收RTCP和RTP的两个端口必须先向服务器的RTCP和RTP端口发送任意的数据,发送方式为UDP,服务器在setup操作时已经返回RTCP和RTP的端口信息。具体的实现参考sendBeforePlay()。我在网上没有找到这么操作的原因,这还是通过wireshark对VLC进行抓包才发现这个隐藏逻辑。
    [java] view plain copy
     
    1. import java.io.IOException;  
    2. import java.nio.channels.SelectionKey;  
    3. import java.nio.channels.Selector;  
    4. import java.util.Iterator;  
    5.   
    6.   
    7. public class PlayerClient {  
    8.     private RTSPClient rtspClient = new RTSPClient();  
    9.     private static final String VERSION = " RTSP/1.0 ";    
    10.     private static final String RTSP_OK = "RTSP/1.0 200 OK";  
    11.     private Selector selector;  
    12.     private enum Status {    
    13.         init, options, describe, setup, play, pause, teardown    
    14.     }  
    15.     private Status sysStatus = Status.init;  
    16.     private String rtspAddress = "rtsp://218.204.223.237:554/live/1/66251FC11353191F/e7ooqwcfbqjoo80j.sdp";  
    17.     private String localAddress = "192.168.31.106";  
    18.     private int localPort=0;  
    19.     private String remoteAddress = "218.204.223.237";  
    20.     private int count=0;  
    21.     private String sessionid;  
    22.     private String trackInfo;  
    23.     private boolean isSended=true;  
    24.     private int localPortOdd=50002;  
    25.     private int localPortEven=50003;  
    26.     private ReceiveSocket socket1 = new ReceiveSocket(localAddress,localPortOdd);  
    27.     private ReceiveSocket socket2 = new ReceiveSocket(localAddress,localPortEven);  
    28.       
    29.     public void init(){  
    30.         rtspClient.setLocalIpAddress(localAddress);  
    31.         rtspClient.setLocalPort(localPort);  
    32.         rtspClient.setRemoteIpAddress(remoteAddress);  
    33.         rtspClient.setRemoteIPort(554);  
    34.         rtspClient.setRtspAddress(rtspAddress);  
    35.         rtspClient.setLocalPortEven(this.localPortEven);  
    36.         rtspClient.setLocalPortOdd(this.localPortOdd);  
    37.         rtspClient.addSocket(this.localPortOdd, socket1);  
    38.         rtspClient.addSocket(this.localPortEven, socket2);  
    39.         try   
    40.         {  
    41.             rtspClient.inital();  
    42.         } catch (IOException e) {  
    43.             e.printStackTrace();  
    44.         }  
    45.         this.selector = rtspClient.getSelector();  
    46.         new Thread(socket1).start();  
    47.         new Thread(socket2).start();  
    48.     }  
    49.       
    50.     public void run() throws IOException{  
    51.         int seq=2;  
    52.         while(true){  
    53.             if(rtspClient.isConnected() && isSended){  
    54.                 switch (sysStatus) {    
    55.                 case init:  
    56.                     byte[] message = RTSPProtocal.encodeOption(this.rtspAddress, this.VERSION, seq);  
    57.                     this.rtspClient.write(message);   
    58.                     break;    
    59.                 case options:  
    60.                     seq++;  
    61.                     message = RTSPProtocal.encodeDescribe(this.rtspAddress, this.VERSION, seq);  
    62.                     this.rtspClient.write(message);     
    63.                     break;    
    64.                 case describe:    
    65.                     seq++;  
    66.                     message = RTSPProtocal.encodeSetup(this.rtspAddress, VERSION, sessionid,   
    67.                                                 localPortEven, localPortOdd,seq, trackInfo);  
    68.                     this.rtspClient.write(message);    
    69.                     break;    
    70.                 case setup:    
    71.                     if(sessionid==null&&sessionid.length()>0){    
    72.                         System.out.println("setup还没有正常返回");    
    73.                     }else{    
    74.                         seq++;  
    75.                         message = RTSPProtocal.encodePlay(this.rtspAddress, VERSION, sessionid, seq);  
    76.                         this.rtspClient.write(message);   
    77.                     }    
    78.                     break;    
    79.                 case play:  
    80.                     count++;  
    81.                     System.out.println("count: "+count);  
    82.                     break;  
    83.                 case pause:     
    84.                     break;    
    85.                 default:    
    86.                     break;    
    87.                 }  
    88.                 isSended=false;  
    89.             }  
    90.             else{  
    91.                   
    92.             }  
    93.             select();  
    94.         }  
    95.     }  
    96.       
    97.     private void handle(byte[] msg) {    
    98.         String tmp = new String(msg);    
    99.         System.out.println("返回内容:"+tmp);    
    100.         if (tmp.startsWith(RTSP_OK)) {    
    101.             switch (sysStatus) {    
    102.             case init:    
    103.                 sysStatus = Status.options;    
    104.                 System.out.println("option ok");  
    105.                 isSended=true;   
    106.                 break;    
    107.             case options:    
    108.                 sysStatus = Status.describe;    
    109.                 trackInfo=tmp.substring(tmp.indexOf("trackID"));    
    110.                 System.out.println("describe ok");   
    111.                 isSended=true;   
    112.                 break;    
    113.             case describe:    
    114.                 sessionid = tmp.substring(tmp.indexOf("Session: ") + 9, tmp    
    115.                         .indexOf("Date:"));    
    116.                 int index = tmp.indexOf("server_port=");  
    117.                 String serverPort1 = tmp.substring(tmp.indexOf("server_port=") + 12, tmp    
    118.                         .indexOf("-", index));  
    119.                 String serverPort2 = tmp.substring(tmp.indexOf("-", index) + 1, tmp    
    120.                         .indexOf(" ", index));  
    121.                   
    122.                 this.rtspClient.setRemotePortEven(Integer.valueOf(serverPort1));  
    123.                 this.rtspClient.setRemotePortOdd(Integer.valueOf(serverPort2));  
    124.                   
    125.                 if(sessionid!=null&&sessionid.length()>0){    
    126.                     sysStatus = Status.setup;    
    127.                     System.out.println("setup ok");    
    128.                 }  
    129.                 isSended=true;   
    130.                 break;    
    131.             case setup:    
    132.                 sysStatus = Status.play;     
    133.                 System.out.println("play ok");   
    134.                 this.rtspClient.sendBeforePlay();  
    135.                 this.rtspClient.sendBeforePlay();  
    136.                 isSended=true;   
    137.                 break;    
    138.             case play:    
    139.                 //sysStatus = Status.pause;    
    140.                 System.out.println("pause ok");    
    141.                 isSended=true;   
    142.                 break;    
    143.             case pause:    
    144.                 sysStatus = Status.teardown;    
    145.                 System.out.println("teardown ok");   
    146.                 isSended=true;   
    147.                 //shutdown.set(true);    
    148.                 break;    
    149.             case teardown:    
    150.                 sysStatus = Status.init;    
    151.                 System.out.println("exit start");   
    152.                 isSended=true;   
    153.                 break;    
    154.             default:    
    155.                 break;    
    156.             }     
    157.         } else {    
    158.             System.out.println("返回错误:" + tmp);    
    159.         }    
    160.     
    161.     }  
    162.       
    163.     private void select() {    
    164.         int n = 0;    
    165.         try   
    166.         {    
    167.             if (selector == null) {    
    168.                 return;    
    169.             }    
    170.             n = selector.select(1000);    
    171.         } catch (final Exception e) {    
    172.             e.printStackTrace();    
    173.         }    
    174.     
    175.         // 如果select返回大于0,处理事件    
    176.         if (n > 0) {    
    177.             for (final Iterator<SelectionKey> i = selector.selectedKeys()    
    178.                     .iterator(); i.hasNext();) {    
    179.                 // 得到下一个Key    
    180.                 final SelectionKey sk = i.next();    
    181.                 i.remove();    
    182.                 // 检查其是否还有效    
    183.                 if (!sk.isValid()) {    
    184.                     continue;    
    185.                 }    
    186.                 if (sk.isReadable()) {    
    187.                     byte[] message = rtspClient.receive();  
    188.                     handle(message);  
    189.                 }  
    190.                 if (sk.isConnectable()) {    
    191.                     try {  
    192.                         rtspClient.reConnect(sk);  
    193.                     } catch (IOException e) {  
    194.                         // TODO Auto-generated catch block  
    195.                         e.printStackTrace();  
    196.                     }    
    197.                 }  
    198.             }    
    199.         }    
    200.     }  
    201.       
    202. }  
    Test:测试类
    [java] view plain copy
     
    1. public class Test {  
    2.     public static void main(String[] args){  
    3.         PlayerClient player = new PlayerClient();  
    4.         player.init();  
    5.         try   
    6.         {  
    7.             player.run();  
    8.         } catch (IOException e) {  
    9.             e.printStackTrace();  
    10.         }  
    11.     }  
    12. }  
       只要在ReceiveSocket的run方法中打断点,你就会发现源源不断的数据向你发来,是不是感觉很爽,哈哈哈。
  • 相关阅读:
    在java中怎样获得当前日期时间
    java 常见异常
    线程中的current thread not owner异常错误
    hibernate 关于hbm.xml编写的总结
    java web 常见异常及解决办法
    初用Ajax
    JavaScript动态修改html组件form的action属性
    Ajax中文乱码的解决
    No repository found error in Installing ADT
    eclipse 安装 CDT
  • 原文地址:https://www.cnblogs.com/developer-ios/p/5919024.html
Copyright © 2011-2022 走看看