原文网址:http://www.cnblogs.com/qq78292959/archive/2010/08/12/2077039.html.

核心提示:rtsp简介(ZT) Real Time Streaming Protocol或者RTSP(实时流媒体协议),是由Real network 和 Netscape共同提出的如何有效地在IP网络上传输流媒体数据的应用层协议。RTSP提供一 种可扩展的框架,使能够提供能控制的,按需传输实时数据,比如音频和视频文件 
rtsp简介(ZT)
Real Time Streaming Protocol或者RTSP(实时流媒体协议),是由Real network 和
Netscape共同提出的如何有效地在IP网络上传输流媒体数据的应用层协议。RTSP提供一
种可扩展的框架,使能够提供能控制的,按需传输实时数据,比如音频和视频文件。源
数据可以包括现场数据的反馈和存贮的文件。rtsp对流媒体提供了诸如暂停,快进等控
制,而它本身并不传输数据,rtsp作用相当于流媒体服务器的远程控制。传输数据可以
通过传输层的tcp,udp协议,rtsp也提供了基于rtp传输机制的一些有效的方法。 
一. 参考资料      
        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回应信息中包括提供的所有可用方法
      使用举例:
      客户端到服务端: 
OPTIONS rtsp://218.207.101.236:554/mobile/3/67A451E937422331 RTSP/1.0
Cseq: 1
     服务端对OPTIONS的回应:
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 1
Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, OPTIONS, ANNOUNCE, RECORD
2.2  DESCRIBE
      C->S:      DESCRIBE request //要求得到S提供的媒体初始化描述信息
      S->C:      DESCRIBE response //S回应媒体初始化描述信息,主要是sdp
     使用举例:
     客户端到服务端:2.4  PLAY
        C->S:      PLAY request //C请求播放
        S->C:      PLAY response //S回应该请求的信息
        客户端到服务端的请求举例:
DESCRIBE rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0
Cseq: 2
      服务端对OPTIONS的回应:
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 2
Content-length: 421
Date: Mon, 03 Aug 2009 08:21:33 GMT
Expires: Mon, 03 Aug 2009 08:21:33 GMT
Content-Type: application/sdp
x-Accept-Retransmit: our-retransmit
x-Accept-Dynamic-Rate: 1
Content-Base: rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/
v=0
o=MediaBox 127992 137813 IN IP4 0.0.0.0
s=RTSP Session
i=Starv Box Live Cast
c=IN IP4 218.207.101.236
t=0 0
a=range:npt=now-
a=control:*
m=video 0 RTP/AVP 96
b=AS:20
a=rtpmap:96 MP4V-ES/1000
a=fmtp:96 profile-level-id=8; config=000001b008000001b5090000010000000120008440fa282c2090a31f; decode_buf=12586
a=range:npt=now-
a=framerate:5
a=framesize:96 176-144
a=cliprect:0,0,144,176
a=control:trackID=1
2.3  SETUP 
        C->S:        SETUP request //设置会话的属性,以及传输模式,提醒S建立会话
        S->C:        SETUP response //S建立会话,返回会话标识符,以及会话相关信息
        客户端到服务端的请求举例:
SETUP rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1
 RTSP/1.0
Cseq: 3
Transport: RTP/AVP;UNICAST;client_port=16264-16265;mode=play
       服务端对客户端的回应举例:
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 3
Session: 26633092229589
Date: Mon, 03 Aug 2009 08:21:33 GMT
Expires: Mon, 03 Aug 2009 08:21:33 GMT
Transport: RTP/AVP;UNICAST;mode=play;client_port=16264-16265;server_port=20026-20027
 
PLAY rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0
Session: 26633092229589
Cseq: 4
       服务端对客户端的回应举例:
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 4
Session: 26633092229589
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回应该请求的信息
        客户端到服务端的请求举例:
PAUSE rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ RTSP/1.0
Cseq: 5
Session: 26633092229589
       服务端对客户端的回应举例:
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 5
Session: 26633092229589
2.6  TEARDOWN 
        C->S:        TEARDOWN request //C请求关闭会话
        S->C:        TEARDOWN response //S回应该请求
        客户端到服务端的请求举例:
TEARDOWN rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ RTSP/1.0
Cseq: 6
User-Agent: RealMedia Player HelixDNAClient/10.0.0.11279 (win32)
Session: 26633092229589
       服务端对客户端的回应举例:
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 6
Session: 26633092229589
Connection: Close
三. RTSP客户端的Java实现
3.1  接口IEvent.java 
      接口IEvent.java的代码如下:
package com.amigo.rtsp;
import java.io.IOException;
import java.nio.channels.SelectionKey;
/** *//**
* IEvent.java 网络事件处理器,当Selector可以进行操作时,调用这个接口中的方法.
* 2007-3-22 下午03:35:51
* @author sycheng
* @version 1.0
*/
public interface IEvent {
    /** *//**
    * 当channel得到connect事件时调用这个方法.
    * @param key
    * @throws IOException
    */
    void connect(SelectionKey key) throws IOException;
    /** *//**
    * 当channel可读时调用这个方法.
    * @param key
    * @throws IOException
    */
    void read(SelectionKey key) throws IOException;
    /** *//**
    * 当channel可写时调用这个方法.
    * @throws IOException
    */
    void write() throws IOException;
    /** *//**
    * 当channel发生错误时调用.
    * @param e
    */
    void error(Exception e);
}
3.2  RTSP的测试类:RTSPClient.java
        RTSP的测试类RTSPClient.java类的代码如下所示:
package com.amigo.rtsp;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicBoolean;
public class RTSPClient extends Thread implements IEvent {
    private static final String VERSION = " RTSP/1.0\r\n";
    private static final String RTSP_OK = "RTSP/1.0 200 OK";
    /** *//** 远程地址 */
    private final InetSocketAddress remoteAddress;
    /** *//** * 本地地址 */
    private final InetSocketAddress localAddress;
    /** *//** * 连接通道 */
    private SocketChannel socketChannel;
    /** *//** 发送缓冲区 */
    private final ByteBuffer sendBuf;
    /** *//** 接收缓冲区 */
    private final ByteBuffer receiveBuf;
    private static final int BUFFER_SIZE = 8192;
    /** *//** 端口选择器 */
    private Selector selector;
    private String address;
    private Status sysStatus;
    private String sessionid;
    /** *//** 线程是否结束的标志 */
    private AtomicBoolean shutdown;
    
    private int seq=1;
    
    private boolean isSended;
    
    private String trackInfo;
    
    private enum Status {
        init, options, describe, setup, play, pause, teardown
    }
    public RTSPClient(InetSocketAddress remoteAddress,
            InetSocketAddress localAddress, String address) {
        this.remoteAddress = remoteAddress;
        this.localAddress = localAddress;
        this.address = address;
        // 初始化缓冲区
        sendBuf = ByteBuffer.allocateDirect(BUFFER_SIZE);
        receiveBuf = ByteBuffer.allocateDirect(BUFFER_SIZE);
        if (selector == null) {
            // 创建新的Selector
            try {
                selector = Selector.open();
            } catch (final IOException e) {
                e.printStackTrace();
            }
        }
        startup();
        sysStatus = Status.init;
        shutdown=new AtomicBoolean(false);
        isSended=false;
    }
    public void startup() {
        try {
            // 打开通道
            socketChannel = SocketChannel.open();
            // 绑定到本地端口
            socketChannel.socket().setSoTimeout(30000);
            socketChannel.configureBlocking(false);
            socketChannel.socket().bind(localAddress);
            if (socketChannel.connect(remoteAddress)) {
                System.out.println("开始建立连接:" + remoteAddress);
            }
            socketChannel.register(selector, SelectionKey.OP_CONNECT
                    | SelectionKey.OP_READ | SelectionKey.OP_WRITE, this);
            System.out.println("端口打开成功");
        } catch (final IOException e1) {
            e1.printStackTrace();
        }
    }
    public void send(byte[] out) {
        if (out == null || out.length < 1) {
            return;
        }
        synchronized (sendBuf) {
            sendBuf.clear();
            sendBuf.put(out);
            sendBuf.flip();
        }
        // 发送出去
        try {
            write();
            isSended=true;
        } catch (final IOException e) {
            e.printStackTrace();
        }
    }
    public void write() throws IOException {
        if (isConnected()) {
            try {
                socketChannel.write(sendBuf);
            } catch (final IOException e) {
            }
        } else {
            System.out.println("通道为空或者没有连接上");
        }
    }
    public byte[] recieve() {
        if (isConnected()) {
            try {
                int len = 0;
                int readBytes = 0;
                synchronized (receiveBuf) {
                    receiveBuf.clear();
                    try {
                        while ((len = socketChannel.read(receiveBuf)) > 0) {
                            readBytes += len;
                        }
                    } finally {
                        receiveBuf.flip();
                    }
                    if (readBytes > 0) {
                        final byte[] tmp = new byte[readBytes];
                        receiveBuf.get(tmp);
                        return tmp;
                    } else {
                        System.out.println("接收到数据为空,重新启动连接");
                        return null;
                    }
                }
            } catch (final IOException e) {
                System.out.println("接收消息错误:");
            }
        } else {
            System.out.println("端口没有连接");
        }
        return null;
    }
    public boolean isConnected() {
        return socketChannel != null && socketChannel.isConnected();
    }
    private void select() {
        int n = 0;
        try {
            if (selector == null) {
                return;
            }
            n = selector.select(1000);
        } catch (final Exception e) {
            e.printStackTrace();
        }
        // 如果select返回大于0,处理事件
        if (n > 0) {
            for (final Iterator<SelectionKey> i = selector.selectedKeys()
                    .iterator(); i.hasNext();) {
                // 得到下一个Key
                final SelectionKey sk = i.next();
                i.remove();
                // 检查其是否还有效
                if (!sk.isValid()) {
                    continue;
                }
                // 处理事件
                final IEvent handler = (IEvent) sk.attachment();
                try {
                    if (sk.isConnectable()) {
                        handler.connect(sk);
                    } else if (sk.isReadable()) {
                        handler.read(sk);
                    } else {
                        // System.err.println("Ooops");
                    }
                } catch (final Exception e) {
                    handler.error(e);
                    sk.cancel();
                }
            }
        }
    }
    public void shutdown() {
        if (isConnected()) {
            try {
                socketChannel.close();
                System.out.println("端口关闭成功");
            } catch (final IOException e) {
                System.out.println("端口关闭错误:");
            } finally {
                socketChannel = null;
            }
        } else {
            System.out.println("通道为空或者没有连接");
        }
    }
    @Override
    public void run() {
        // 启动主循环流程
        while (!shutdown.get()) {
            try {
                if (isConnected()&&(!isSended)) {
                    switch (sysStatus) {
                    case init:
                        doOption();
                        break;
                    case options:
                        doDescribe();
                        break;
                    case describe:
                        doSetup();
                        break;
                    case setup:
                        if(sessionid==null&&sessionid.length()>0){
                            System.out.println("setup还没有正常返回");
                        }else{
                            doPlay();
                        }
                        break;
                    case play:
                        doPause();
                        break;
                        
                    case pause:
                        doTeardown();
                        break;
                    default:
                        break;
                    }
                }
                // do select
                select();
                try {
                    Thread.sleep(1000);
                } catch (final Exception e) {
                }
            } catch (final Exception e) {
                e.printStackTrace();
            }
        }
        
        shutdown();
    }
    public void connect(SelectionKey key) throws IOException {
        if (isConnected()) {
            return;
        }
        // 完成SocketChannel的连接
        socketChannel.finishConnect();
        while (!socketChannel.isConnected()) {
            try {
                Thread.sleep(300);
            } catch (final InterruptedException e) {
                e.printStackTrace();
            }
            socketChannel.finishConnect();
        }
    }
    public void error(Exception e) {
        e.printStackTrace();
    }
    public void read(SelectionKey key) throws IOException {
        // 接收消息
        final byte[] msg = recieve();
        if (msg != null) {
            handle(msg);
        } else {
            key.cancel();
        }
    }
    private void handle(byte[] msg) {
        String tmp = new String(msg);
        System.out.println("返回内容:");
        System.out.println(tmp);
        if (tmp.startsWith(RTSP_OK)) {
            switch (sysStatus) {
            case init:
                sysStatus = Status.options;
                break;
            case options:
                sysStatus = Status.describe;
                trackInfo=tmp.substring(tmp.indexOf("trackID"));
                break;
            case describe:
                sessionid = tmp.substring(tmp.indexOf("Session: ") + 9, tmp
                        .indexOf("Date:"));
                if(sessionid!=null&&sessionid.length()>0){
                    sysStatus = Status.setup;
                }
                break;
            case setup:
                sysStatus = Status.play;
                break;
            case play:
                sysStatus = Status.pause;
                break;
            case pause:
                sysStatus = Status.teardown;
                shutdown.set(true);
                break;
            case teardown:
                sysStatus = Status.init;
                break;
            default:
                break;
            }
            isSended=false;
        } else {
            System.out.println("返回错误:" + tmp);
        }
    }
    private void doTeardown() {
        StringBuilder sb = new StringBuilder();
        sb.append("TEARDOWN ");
        sb.append(this.address);
        sb.append("/");
        sb.append(VERSION);
        sb.append("Cseq: ");
        sb.append(seq++);
        sb.append("\r\n");
        sb.append("User-Agent: RealMedia Player HelixDNAClient/10.0.0.11279 (win32)\r\n");
        sb.append("Session: ");
        sb.append(sessionid);
        sb.append("\r\n");
        send(sb.toString().getBytes());
        System.out.println(sb.toString());
    }
    private void doPlay() {
        StringBuilder sb = new StringBuilder();
        sb.append("PLAY ");
        sb.append(this.address);
        sb.append(VERSION);
        sb.append("Session: ");
        sb.append(sessionid);
        sb.append("Cseq: ");
        sb.append(seq++);
        sb.append("\r\n");
        sb.append("\r\n");
        System.out.println(sb.toString());
        send(sb.toString().getBytes());
    }
    private void doSetup() {
        StringBuilder sb = new StringBuilder();
        sb.append("SETUP ");
        sb.append(this.address);
        sb.append("/");
        sb.append(trackInfo);
        sb.append(VERSION);
        sb.append("Cseq: ");
        sb.append(seq++);
        sb.append("\r\n");
        sb.append("Transport: RTP/AVP;UNICAST;client_port=16264-16265;mode=play\r\n");
        sb.append("\r\n");
        System.out.println(sb.toString());
        send(sb.toString().getBytes());
    }
    private void doOption() {
        StringBuilder sb = new StringBuilder();
        sb.append("OPTIONS ");
        sb.append(this.address.substring(0, address.lastIndexOf("/")));
        sb.append(VERSION);
        sb.append("Cseq: ");
        sb.append(seq++);
        sb.append("\r\n");
        sb.append("\r\n");
        System.out.println(sb.toString());
        send(sb.toString().getBytes());
    }
    private void doDescribe() {
        StringBuilder sb = new StringBuilder();
        sb.append("DESCRIBE ");
        sb.append(this.address);
        sb.append(VERSION);
        sb.append("Cseq: ");
        sb.append(seq++);
        sb.append("\r\n");
        sb.append("\r\n");
        System.out.println(sb.toString());
        send(sb.toString().getBytes());
    }
    
    private void doPause() {
        StringBuilder sb = new StringBuilder();
        sb.append("PAUSE ");
        sb.append(this.address);
        sb.append("/");
        sb.append(VERSION);
        sb.append("Cseq: ");
        sb.append(seq++);
        sb.append("\r\n");
        sb.append("Session: ");
        sb.append(sessionid);
        sb.append("\r\n");
        send(sb.toString().getBytes());
        System.out.println(sb.toString());
    }
    
    public static void main(String[] args) {
        try {
            // RTSPClient(InetSocketAddress remoteAddress,
            // InetSocketAddress localAddress, String address)
            RTSPClient client = new RTSPClient(
                    new InetSocketAddress("218.207.101.236", 554),
                    new InetSocketAddress("192.168.2.28", 0),
                    "rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp");
            client.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
       其中:rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp为我在网上找到的一个rtsp的sdp地址,读者可自行更换,RTSP的默认端口为554.
3.3  运行结果
       运行RTSPClient.java,运行结果如下所示:
端口打开成功
OPTIONS rtsp://218.207.101.236:554/mobile/3/67A451E937422331 RTSP/1.0
Cseq: 1

返回内容:
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 1
Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, OPTIONS, ANNOUNCE, RECORD

DESCRIBE rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0
Cseq: 2

返回内容:
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 2
Content-length: 421
Date: Mon, 03 Aug 2009 08:50:36 GMT
Expires: Mon, 03 Aug 2009 08:50:36 GMT
Content-Type: application/sdp
x-Accept-Retransmit: our-retransmit
x-Accept-Dynamic-Rate: 1
Content-Base: rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/
v=0
o=MediaBox 127992 137813 IN IP4 0.0.0.0
s=RTSP Session
i=Starv Box Live Cast
c=IN IP4 218.207.101.236
t=0 0
a=range:npt=now-
a=control:*
m=video 0 RTP/AVP 96
b=AS:20
a=rtpmap:96 MP4V-ES/1000
a=fmtp:96 profile-level-id=8; config=000001b008000001b5090000010000000120008440fa282c2090a31f; decode_buf=12586
a=range:npt=now-
a=framerate:5
a=framesize:96 176-144
a=cliprect:0,0,144,176
a=control:trackID=1
SETUP rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1
 RTSP/1.0
Cseq: 3
Transport: RTP/AVP;UNICAST;client_port=16264-16265;mode=play

返回内容:
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 3
Session: 15470472221769
Date: Mon, 03 Aug 2009 08:50:36 GMT
Expires: Mon, 03 Aug 2009 08:50:36 GMT
Transport: RTP/AVP;UNICAST;mode=play;client_port=16264-16265;server_port=20080-20081

PLAY rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0
Session: 15470472221769
Cseq: 4

返回内容:
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 4
Session: 15470472221769
RTP-Info: url=rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1;seq=0;rtptime=0

PAUSE rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ RTSP/1.0
Cseq: 5
Session: 15470472221769

返回内容:
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 5
Session: 15470472221769

TEARDOWN rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ RTSP/1.0
Cseq: 6
User-Agent: RealMedia Player HelixDNAClient/10.0.0.11279 (win32)
Session: 15470472221769

返回内容:
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 6
Session: 15470472221769
Connection: Close

端口关闭成功

【转】RTSP实例解析的更多相关文章

  1. RTSP实例解析

    以下是某地IPTV的RTSP协商过程: 1.DESCRIBE 请求: //方法和媒体URL DESCRIBE rtsp://118.122.89.27:554/live/ch1008312159479 ...

  2. exec函数族实例解析

    exec函数族实例解析 fork()函数通过系统调用创建一个与原来进程(父进程)几乎完全相同的进程(子进程是父进程的副本,它将获得父进程数据空间.堆.栈等资源的副本.注意,子进程持有的是上述存储空间的 ...

  3. [Reprint] C++函数模板与类模板实例解析

    这篇文章主要介绍了C++函数模板与类模板,需要的朋友可以参考下   本文针对C++函数模板与类模板进行了较为详尽的实例解析,有助于帮助读者加深对C++函数模板与类模板的理解.具体内容如下: 泛型编程( ...

  4. [Reprint]C++普通函数指针与成员函数指针实例解析

    这篇文章主要介绍了C++普通函数指针与成员函数指针,很重要的知识点,需要的朋友可以参考下   C++的函数指针(function pointer)是通过指向函数的指针间接调用函数.相信很多人对指向一般 ...

  5. JavaWeb实现文件上传下载功能实例解析

    转:http://www.cnblogs.com/xdp-gacl/p/4200090.html JavaWeb实现文件上传下载功能实例解析 在Web应用系统开发中,文件上传和下载功能是非常常用的功能 ...

  6. Android实例-Delphi开发蓝牙官方实例解析(XE10+小米2+小米5)

    相关资料:1.http://blog.csdn.net/laorenshen/article/details/411498032.http://www.cnblogs.com/findumars/p/ ...

  7. Android开发之IPC进程间通信-AIDL介绍及实例解析

    一.IPC进程间通信 IPC是进程间通信方法的统称,Linux IPC包括以下方法,Android的进程间通信主要采用是哪些方法呢? 1. 管道(Pipe)及有名管道(named pipe):管道可用 ...

  8. easyUI:ComboTree and comselector使用实例解析

    ComboTree 使用场景:故名思意,ComboTree是combox和Tree的结合体,在需要通过选择得到某一个node值的时候触发. 栗子: 定义: 使用标签创建树形下拉框. Comselect ...

  9. Maven--多模块依赖实例解析(五)

    <Maven--搭建开发环境(一)> <Maven--构建企业级仓库(二)> <Maven—几个需要补充的问题(三)> <Maven—生命周期和插件(四)&g ...

随机推荐

  1. HDU 5596/BestCoder Round #66 (div.2) GTW likes math 签到

    GTW likes math  Memory Limit: 131072/131072 K (Java/Others) 问题描述 某一天,GTW听了数学特级教师金龙鱼的课之后,开始做数学<从自主 ...

  2. Node.js缓冲模块Buffer

    前言 Javascript是为浏览器而设计的,能很好的处理unicode编码的字符串,但对于二进制或非unicode编码的数据就显得无能为力. Node.js继承Javascript的语言特性,同时又 ...

  3. 深入理解Windows X64调试

    随着64位操作系统的普及,都开始大力进军x64,X64下的调试机制也发生了改变,与x86相比,添加了许多自己的新特性,之前学习了Windows x64的调试机制,这里本着“拿来主义”的原则与大家分享. ...

  4. 天使投资、VC 以及 PE 的区别是什么?

    如果满足于“阶段不同”这个简单的回答,那你可能错过了一个思考资本与企业发展之间关系的机会. 首先要交待一下,在大众语境中,angel/VC/PE三者都可认为是VC,也就是人们常说的风险投资,在国内官方 ...

  5. React-非dom属性-dangerouslySetInnerHTML标签

    <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8& ...

  6. 【ArcEngine入门与提高】Element(元素)、Annotation(注记)旋转

    因项目需要,需要做一个旋转注记的工具.因为注记这玩意用的比较少,网上资源也很少,所以做起来相当头疼.在经过一番研究之后,终于搞清楚注记的存储原理了,原来是和Element的类似,只不过注记是要把Ele ...

  7. SQL SERVER ->> Columnstore Index

    谈到Columnstore index就不得不提SQL SERVER的压缩技术了.Columnstore就是用到了SQL SERVER的压缩技术.Columnstore又分Columnstore和Co ...

  8. Java数据结构之排序

    1.冒泡排序:时间复杂度为O(n2) 假设是由小到大排序:相邻两个数之间进行比较,较大的数在后面.一次比较过后最大的数排在最后面 如:40.8.15.18.12一次排序后为:8.15.18.12.40 ...

  9. jdk、apache-ant结合yuicompressor配置的CSS与JS合并压缩工具

    前序:网上很多css与js合并打包工具,其中最流行的就是ant结合yui-compressor,鉴于学习与工作需要今天就学习了一下这种方式,供大家学习交流. 步骤:1.安装jdk,并配置其变量环境:有 ...

  10. 浅析CSS负边距

    本文主要讨论两点,1.左右负边距对元素宽度的影响:2.负边距对浮动元素的影响. 在讨论这两点前,首先要理解盒模型.文档流. 盒模型,见下图,简单明了. 文档流,将窗体自上而下分成一行行, 并在每行中按 ...