﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-专注电子商务-随笔分类-底层架构</title><link>http://www.blogjava.net/mikechen/category/50936.html</link><description>电子商务技术架构</description><language>zh-cn</language><lastBuildDate>Fri, 30 Mar 2012 03:32:33 GMT</lastBuildDate><pubDate>Fri, 30 Mar 2012 03:32:33 GMT</pubDate><ttl>60</ttl><item><title>Hadoop-详解</title><link>http://www.blogjava.net/mikechen/archive/2012/03/30/373028.html</link><dc:creator>陈睿</dc:creator><author>陈睿</author><pubDate>Fri, 30 Mar 2012 02:14:00 GMT</pubDate><guid>http://www.blogjava.net/mikechen/archive/2012/03/30/373028.html</guid><wfw:comment>http://www.blogjava.net/mikechen/comments/373028.html</wfw:comment><comments>http://www.blogjava.net/mikechen/archive/2012/03/30/373028.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mikechen/comments/commentRss/373028.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mikechen/services/trackbacks/373028.html</trackback:ping><description><![CDATA[之前有接触过hadoop，但都比较浅显，对立面的东东不是很清楚！<br />打算后面在hadoop上花时间把里面的内容，好好学学，这篇博客将在后面陆续更新hadoop学习笔记。<img src ="http://www.blogjava.net/mikechen/aggbug/373028.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mikechen/" target="_blank">陈睿</a> 2012-03-30 10:14 <a href="http://www.blogjava.net/mikechen/archive/2012/03/30/373028.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>底层架构-远程通讯-Mina</title><link>http://www.blogjava.net/mikechen/archive/2012/03/15/371938.html</link><dc:creator>陈睿</dc:creator><author>陈睿</author><pubDate>Thu, 15 Mar 2012 06:49:00 GMT</pubDate><guid>http://www.blogjava.net/mikechen/archive/2012/03/15/371938.html</guid><wfw:comment>http://www.blogjava.net/mikechen/comments/371938.html</wfw:comment><comments>http://www.blogjava.net/mikechen/archive/2012/03/15/371938.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mikechen/comments/commentRss/371938.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mikechen/services/trackbacks/371938.html</trackback:ping><description><![CDATA[<strong>一：Mina概要</strong><br />&nbsp; &nbsp;&nbsp;Apache Mina是一个能够帮助用户开发高性能和高伸缩性网络应用程序的框架。它通过Java nio技术基于TCP/IP和UDP/IP协议提供了抽象的、事件驱动的、异步的API。<div>如下的特性：</div><div>1、 &nbsp;基于Java nio的TCP/IP和UDP/IP实现</div><div>基于RXTX的串口通信（RS232）</div><div>VM 通道通信</div><div>2、通过filter接口实现扩展，类似于Servlet filters</div><div>3、low-level（底层）和high-level（高级封装）的api：</div><div>&nbsp; &nbsp; &nbsp; &nbsp;low-level：使用ByteBuffers</div><div>&nbsp; &nbsp; &nbsp; &nbsp;High-level：使用自定义的消息对象和解码器</div><div>4、Highly customizable（易用的）线程模式（MINA2.0 已经禁用线程模型了）：</div><div>&nbsp; &nbsp; &nbsp; &nbsp;单线程</div><div>&nbsp; &nbsp; &nbsp; &nbsp;线程池</div><div>&nbsp; &nbsp; &nbsp; &nbsp;多个线程池</div><div>5、基于java5 SSLEngine的SSL、TLS、StartTLS支持</div><div>6、负载平衡</div><div>7、使用mock进行单元测试</div><div>8、jmx整合</div><div>9、基于StreamIoHandler的流式I/O支持</div><div>10、IOC容器的整合：Spring、PicoContainer</div><div>11、平滑迁移到Netty平台<br /><br /><strong>二：实践</strong><br />&nbsp; &nbsp; 首先讲一下客户端的通信过程：<br /><div>1.通过SocketConnector同服务器端建立连接&nbsp;</div><div>2.链接建立之后I/O的读写交给了I/O Processor线程，I/O Processor是多线程的&nbsp;</div><div>3.通过I/O Processor读取的数据经过IoFilterChain里所有配置的IoFilter，IoFilter进行消息的过滤，格式的转换，在这个层面可以制定一些自定义的协议&nbsp;</div><div>4.最后IoFilter将数据交给Handler进行业务处理，完成了整个读取的过程&nbsp;</div><div>5.写入过程也是类似，只是刚好倒过来，通过IoSession.write写出数据，然后Handler进行写入的业务处理，处理完成后交给IoFilterChain，进行消息过滤和协议的转换，最后通过I/O Processor将数据写出到socket通道&nbsp;</div><div>IoFilterChain作为消息过滤链&nbsp;</div><div>1.读取的时候是从低级协议到高级协议的过程，一般来说从byte字节逐渐转换成业务对象的过程&nbsp;</div><div>2.写入的时候一般是从业务对象到字节byte的过程&nbsp;</div><div>IoSession贯穿整个通信过程的始终&nbsp;</div>&nbsp; &nbsp;&nbsp;<strong style="font-weight: bold; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; text-align: left; background-color: #efefef; ">客户端通信过程</strong>&nbsp;</div><span style="text-align: left; background-color: #efefef; "><font face="Helvetica, Tahoma, Arial, sans-serif"><span style="line-height: 25px;"><br /></span></font></span>&nbsp; &nbsp;<img src="http://www.blogjava.net/images/blogjava_net/mikechen/mina.png" border="0" alt="" width="718" height="341" /><br />1.创建服务器<br />&nbsp; &nbsp;&nbsp;<span style="background-color: #eeeeee; font-size: 13px; color: #0000ff; ">package</span><span style="background-color: #eeeeee; font-size: 13px; ">&nbsp;com.gewara.web.module.base;</span><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><br /><span style="color: #0000FF; ">import</span>&nbsp;java.io.IOException;<br /><span style="color: #0000FF; ">import</span>&nbsp;java.net.InetSocketAddress;<br /><span style="color: #0000FF; ">import</span>&nbsp;java.nio.charset.Charset;<br /><br /><span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.core.service.IoAcceptor;<br /><span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.filter.codec.ProtocolCodecFilter;<br /><span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.filter.codec.textline.TextLineCodecFactory;<br /><span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.filter.logging.LoggingFilter;<br /><span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.transport.socket.nio.NioSocketAcceptor;<br /><br /><span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;*&nbsp;Mina服务器<br />&nbsp;*&nbsp;<br />&nbsp;*&nbsp;</span><span style="color: #808080; ">@author</span><span style="color: #008000; ">&nbsp;mike<br />&nbsp;*<br />&nbsp;*&nbsp;</span><span style="color: #808080; ">@since</span><span style="color: #008000; ">&nbsp;2012-3-15<br />&nbsp;</span><span style="color: #008000; ">*/</span><br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;HelloServer&nbsp;{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;PORT&nbsp;=&nbsp;8901;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;定义监听端口</span><span style="color: #008000; "><br /></span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(String[]&nbsp;args)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;IOException{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;创建服务端监控线程</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IoAcceptor&nbsp;acceptor&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;NioSocketAcceptor();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;设置日志记录器</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;acceptor.getFilterChain().addLast("logger",&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;LoggingFilter());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;设置编码过滤器</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;acceptor.getFilterChain().addLast("codec",<span style="color: #0000FF; ">new</span>&nbsp;ProtocolCodecFilter(<span style="color: #0000FF; ">new</span>&nbsp;TextLineCodecFactory(Charset.forName("UTF-8"))));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;指定业务逻辑处理器</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;acceptor.setHandler(<span style="color: #0000FF; ">new</span>&nbsp;HelloServerHandler());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;设置端口号</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;acceptor.setDefaultLocalAddress(<span style="color: #0000FF; ">new</span>&nbsp;InetSocketAddress(PORT));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;启动监听线程</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;acceptor.bind();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</div>&nbsp;<br />2.创建服务器端业务逻辑<br />&nbsp;&nbsp;&nbsp;&nbsp;<br /><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">package</span>&nbsp;com.gewara.web.module.base;<br /><br /><span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.core.service.IoHandlerAdapter;<br /><span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.core.session.IoSession;<br /><br /><span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;*&nbsp;服务器端业务逻辑<br />&nbsp;*&nbsp;<br />&nbsp;*&nbsp;</span><span style="color: #808080; ">@author</span><span style="color: #008000; ">&nbsp;mike<br />&nbsp;*<br />&nbsp;*&nbsp;</span><span style="color: #808080; ">@since</span><span style="color: #008000; ">&nbsp;2012-3-15<br />&nbsp;</span><span style="color: #008000; ">*/</span><br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;HelloServerHandler&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;IoHandlerAdapter&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;连接创建事件<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;sessionCreated(IoSession&nbsp;session){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;显示客户端的ip和端口</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(session.getRemoteAddress().toString());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;消息接收事件<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;messageReceived(IoSession&nbsp;session,&nbsp;Object&nbsp;message)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;str&nbsp;=&nbsp;message.toString();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(str.trim().equalsIgnoreCase("quit")){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;结束会话</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.close(<span style="color: #0000FF; ">true</span>);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;返回消息字符串</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.write("Hi&nbsp;Client!");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;打印客户端传来的消息内容</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Message&nbsp;written<img src="http://www.blogjava.net/Images/dot.gif" alt="" />"&nbsp;+&nbsp;str);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</div><br />3.创建客户端<br />&nbsp; &nbsp; &nbsp;<span style="background-color: #eeeeee; font-size: 13px; color: #0000ff; ">package</span><span style="background-color: #eeeeee; font-size: 13px; ">&nbsp;com.gewara.web.module.base;</span><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><br /><span style="color: #0000FF; ">import</span>&nbsp;java.net.InetSocketAddress;<br /><span style="color: #0000FF; ">import</span>&nbsp;java.nio.charset.Charset;<br /><br /><span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.core.future.ConnectFuture;<br /><span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.filter.codec.ProtocolCodecFilter;<br /><span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.filter.codec.textline.TextLineCodecFactory;<br /><span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.filter.logging.LoggingFilter;<br /><span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.transport.socket.nio.NioSocketConnector;<br /><br /><span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;*&nbsp;Mina客户端<br />&nbsp;*&nbsp;<br />&nbsp;*&nbsp;</span><span style="color: #808080; ">@author</span><span style="color: #008000; ">&nbsp;mike<br />&nbsp;*<br />&nbsp;*&nbsp;</span><span style="color: #808080; ">@since</span><span style="color: #008000; ">&nbsp;2012-3-15<br />&nbsp;</span><span style="color: #008000; ">*/</span><br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;HelloClient&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(String[]&nbsp;args){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;创建客户端连接器.</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NioSocketConnector&nbsp;connector&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;NioSocketConnector();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;设置日志记录器</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connector.getFilterChain().addLast("logger",&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;LoggingFilter());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;设置编码过滤器</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connector.getFilterChain().addLast("codec",&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;ProtocolCodecFilter(<span style="color: #0000FF; ">new</span>&nbsp;TextLineCodecFactory(Charset.forName("UTF-8"))));&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;设置连接超时检查时间</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connector.setConnectTimeoutCheckInterval(30);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;设置事件处理器</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connector.setHandler(<span style="color: #0000FF; ">new</span>&nbsp;HelloClientHandler());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;建立连接</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ConnectFuture&nbsp;cf&nbsp;=&nbsp;connector.connect(<span style="color: #0000FF; ">new</span>&nbsp;InetSocketAddress("192.168.2.89",&nbsp;8901));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;等待连接创建完成</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cf.awaitUninterruptibly();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;发送消息&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cf.getSession().write("Hi&nbsp;Server!");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;发送消息</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cf.getSession().write("quit");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;等待连接断开</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cf.getSession().getCloseFuture().awaitUninterruptibly();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;释放连接</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connector.dispose();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</div><br />4.客户端业务逻辑<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">package</span>&nbsp;com.gewara.web.module.base;<br /><br /><span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.core.service.IoHandlerAdapter;<br /><span style="color: #0000FF; ">import</span>&nbsp;org.apache.mina.core.session.IoSession;<br /><br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;HelloClientHandler&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;IoHandlerAdapter&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;消息接收事件<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;messageReceived(IoSession&nbsp;session,&nbsp;Object&nbsp;message)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">显示接收到的消息</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("server&nbsp;message:"+message.toString());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</div><br />5.先启动服务器端，然后启动客户端<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->2012-03-15&nbsp;14:45:41,456&nbsp;&nbsp;INFO&nbsp;&nbsp;logging.LoggingFilter&nbsp;-&nbsp;CREATED<br />/192.168.2.89:2691<br />2012-03-15&nbsp;14:45:41,456&nbsp;&nbsp;INFO&nbsp;&nbsp;logging.LoggingFilter&nbsp;-&nbsp;OPENED<br />2012-03-15&nbsp;14:45:41,487&nbsp;&nbsp;INFO&nbsp;&nbsp;logging.LoggingFilter&nbsp;-&nbsp;RECEIVED:&nbsp;HeapBuffer[pos=0&nbsp;lim=11&nbsp;cap=2048:&nbsp;48&nbsp;69&nbsp;20&nbsp;53&nbsp;65&nbsp;72&nbsp;76&nbsp;65&nbsp;72&nbsp;21&nbsp;0A]<br />2012-03-15&nbsp;14:45:41,487&nbsp;&nbsp;DEBUG&nbsp;codec.ProtocolCodecFilter&nbsp;-&nbsp;Processing&nbsp;a&nbsp;MESSAGE_RECEIVED&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;session&nbsp;1<br />Message&nbsp;written<img src="http://www.blogjava.net/Images/dot.gif" alt="" />Hi&nbsp;Server!<br />2012-03-15&nbsp;14:45:41,487&nbsp;&nbsp;INFO&nbsp;&nbsp;logging.LoggingFilter&nbsp;-&nbsp;SENT:&nbsp;HeapBuffer[pos=0&nbsp;lim=0&nbsp;cap=0:&nbsp;empty]<br />2012-03-15&nbsp;14:45:41,487&nbsp;&nbsp;INFO&nbsp;&nbsp;logging.LoggingFilter&nbsp;-&nbsp;RECEIVED:&nbsp;HeapBuffer[pos=0&nbsp;lim=5&nbsp;cap=2048:&nbsp;71&nbsp;75&nbsp;69&nbsp;74&nbsp;0A]<br />2012-03-15&nbsp;14:45:41,487&nbsp;&nbsp;DEBUG&nbsp;codec.ProtocolCodecFilter&nbsp;-&nbsp;Processing&nbsp;a&nbsp;MESSAGE_RECEIVED&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;session&nbsp;1<br />2012-03-15&nbsp;14:45:41,487&nbsp;&nbsp;INFO&nbsp;&nbsp;logging.LoggingFilter&nbsp;-&nbsp;CLOSED</div><br /><strong>三:分析源码<br /></strong>1.首先看服务器<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;创建服务端监控线程</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IoAcceptor&nbsp;acceptor&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;NioSocketAcceptor();<br />&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;设置日志记录器</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;acceptor.getFilterChain().addLast("logger",&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;LoggingFilter());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;设置编码过滤器</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;acceptor.getFilterChain().addLast("codec",<span style="color: #0000FF; ">new</span>&nbsp;ProtocolCodecFilter(<span style="color: #0000FF; ">new</span>&nbsp;TextLineCodecFactory(Charset.forName("UTF-8"))));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;指定业务逻辑处理器</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;acceptor.setHandler(<span style="color: #0000FF; ">new</span>&nbsp;HelloServerHandler());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;设置端口号</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;acceptor.setDefaultLocalAddress(<span style="color: #0000FF; ">new</span>&nbsp;InetSocketAddress(PORT));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;启动监听线程</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;acceptor.bind();</div><br />&nbsp;<strong> 1)先创建<span style="font-size: 13px; background-color: #eeeeee; ">NioSocketAcceptor</span>&nbsp;nio的接收器，谈到Socket就要说到<span style="color: #212121; font-family: Verdana; background-color: #ffffff; ">Reactor模式</span>&nbsp;</strong><br />&nbsp; &nbsp;&nbsp;<span style="color: #212121; font-family: Verdana; background-color: #ffffff; ">当前分布式计算　Web Services盛行天下，这些网络服务的底层都离不开对socket的操作。他们都有一个共同的结构：</span><br style="color: #212121; font-family: Verdana; background-color: #ffffff; " /><span style="color: #212121; font-family: Verdana; background-color: #ffffff; ">1. Read request</span><br style="color: #212121; font-family: Verdana; background-color: #ffffff; " /><span style="color: #212121; font-family: Verdana; background-color: #ffffff; ">2. Decode request</span><br style="color: #212121; font-family: Verdana; background-color: #ffffff; " /><span style="color: #212121; font-family: Verdana; background-color: #ffffff; ">3. Process service &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><br style="color: #212121; font-family: Verdana; background-color: #ffffff; " /><span style="color: #212121; font-family: Verdana; background-color: #ffffff; ">4. Encode reply</span><br style="color: #212121; font-family: Verdana; background-color: #ffffff; " /><span style="color: #212121; font-family: Verdana; background-color: #ffffff; ">5. Send reply</span>&nbsp;<br /><img src="http://www.blogjava.net/images/blogjava_net/mikechen/mina-reactor-classic.jpg" border="0" alt="" width="400" height="167" /><br /><p style="color: #212121; font-family: Verdana; background-color: #ffffff; ">但这种模式在用户负载增加时，性能将下降非常的快。我们需要重新寻找一个新的方案，保持数据处理的流畅，很显然，事件触发机制是最好的解决办法，当有事件发生时，会触动handler,然后开始数据的处理。<br />Reactor模式类似于AWT中的Event处理。</p><p style="color: #212121; font-family: Verdana; background-color: #ffffff; "><strong>Reactor模式参与者</strong></p><p style="color: #212121; font-family: Verdana; background-color: #ffffff; ">1.Reactor 负责响应IO事件，一旦发生，广播发送给相应的Handler去处理,这类似于AWT的thread<br />2.Handler 是负责非堵塞行为，类似于AWT ActionListeners；同时负责将handlers与event事件绑定，类似于AWT addActionListener</p><p style="color: #212121; font-family: Verdana; background-color: #ffffff; "><img src="http://www.blogjava.net/images/blogjava_net/mikechen/mina-reactor.jpg" border="0" alt="" width="400" height="174" /><br />并发系统常采用reactor模式，简称观察者模式，代替常用的多线程处理方式，<strong>利用有限的系统的资源，提高系统的吞吐量</strong>。<br /></p>可以看一下这篇文章，讲解的很生动具体，一看就明白reactor模式的好处<a href="http://daimojingdeyu.iteye.com/blog/828696">http://daimojingdeyu.iteye.com/blog/828696</a>&nbsp;<br /><span style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">Reactor模式是编写高性能网络服务器的必备技术之一，它具有如下的优点：</span><br style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; " /><span style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp; 1）响应快，不必为单个同步时间所阻塞，虽然Reactor本身依然是同步的；</span><br style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; " /><span style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp; 2）编程相对简单，可以最大程度的避免复杂的多线程及同步问题，并且避免了多线程/进程的切换开销；</span><br style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; " /><span style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp; 3）可扩展性，可以方便的通过增加Reactor实例个数来充分利用CPU资源；</span><br style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; " /><span style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp; 4）可复用性，reactor框架本身与具体事件处理逻辑无关，具有很高的复用性；</span>&nbsp;<br /><br /><strong>2)其次，再说说NIO的基本原理和使用</strong><br />&nbsp; &nbsp;&nbsp;NIO 有一个主要的类Selector,这个类似一个观察者，只要我们把需要探知的socketchannel告诉Selector,我们接着做别的事情，当有事件发生时，他会通知我们，传回一组 SelectionKey,我们读取这些Key,就会获得我们刚刚注册过的socketchannel,然后，我们从这个Channel中读取数据，放心，包准能够读到，接着我们可以处理这些数据。<div>　　Selector内部原理实际是在做一个对所注册的channel的轮询访问，不断的轮询(目前就这一个算法)，一旦轮询到一个channel有所注册的事情发生，比如数据来了，他就会站起来报告，交出一把钥匙，让我们通过这把钥匙(SelectionKey表示 SelectableChannel 在 Selector 中的注册的标记。 )来读取这个channel的内容。</div><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><img src ="http://www.blogjava.net/mikechen/aggbug/371938.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mikechen/" target="_blank">陈睿</a> 2012-03-15 14:49 <a href="http://www.blogjava.net/mikechen/archive/2012/03/15/371938.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>底层架构-远程通讯</title><link>http://www.blogjava.net/mikechen/archive/2012/03/12/371703.html</link><dc:creator>陈睿</dc:creator><author>陈睿</author><pubDate>Mon, 12 Mar 2012 01:57:00 GMT</pubDate><guid>http://www.blogjava.net/mikechen/archive/2012/03/12/371703.html</guid><wfw:comment>http://www.blogjava.net/mikechen/comments/371703.html</wfw:comment><comments>http://www.blogjava.net/mikechen/archive/2012/03/12/371703.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/mikechen/comments/commentRss/371703.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mikechen/services/trackbacks/371703.html</trackback:ping><description><![CDATA[<strong>一：基本原理</strong><br />&nbsp; &nbsp; 主要是要实现网络之间的通讯，<span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">网络通信需要做的就是将流从一台计算机传输到另外一台计算机，基于传输协议和网络IO来实现，其中传输协议比较出名的有http、 tcp、udp等等，http、tcp、udp都是在基于Socket概念上为某类应用场景而扩展出的传输协议，网络IO，主要有bio、nio、aio 三种方式，所有的分布式应用通讯都基于这个原理而实现。<br /><br /><strong>二：实践</strong><br /></span><div>在分布式服务框架中，一个最基础的问题就是远程服务是怎么通讯的，在Java领域中有很多可实现远程通讯的技术:RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB和JMS<br />既然引入出了这么多技术，那我们就顺道深入挖掘下去，了解每个技术框架背后的东西：<br />1.首先看RMI<br />&nbsp; &nbsp;&nbsp;<span style="text-align: left; background-color: #ffffff; "><font color="#333333" face="Arial, 宋体, sans-serif"><span style="line-height: 25px;">&nbsp;RMI主要包含如下内容：&nbsp;</span></font><br /><div style="text-align: -webkit-auto; ">&nbsp; &nbsp; &nbsp;<font color="#333333" face="Arial, 宋体, sans-serif"><span style="line-height: 25px;">远程服务的接口定义&nbsp;</span></font></div></span><span style="color: #333333; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#183;远程服务接口的具体实现&nbsp;</span><br style="color: #333333; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; " /><span style="color: #333333; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#183;桩（Stub）和</span><a title="框架" href="http://www.hudong.com/wiki/%E6%A1%86%E6%9E%B6" target="_blank" style="color: #0268cd; text-decoration: none; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">框架</a><span style="color: #333333; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">（Skeleton）</span><a title="文件" href="http://www.hudong.com/wiki/%E6%96%87%E4%BB%B6" target="_new" style="color: #0268cd; text-decoration: none; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">文件</a>&nbsp;<br style="color: #333333; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; " /><span style="color: #333333; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#183;一个运行远程服务的服务器&nbsp;</span><br style="color: #333333; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; " /><span style="color: #333333; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#183;一个RMI命名服务，它允许</span><a title="客户端" href="http://www.hudong.com/wiki/%E5%AE%A2%E6%88%B7%E7%AB%AF" target="_new" style="color: #0268cd; text-decoration: none; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">客户端</a><span style="color: #333333; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">去发现这个远程服务&nbsp;</span><br style="color: #333333; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; " /><span style="color: #333333; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#183;</span><a title="类" href="http://www.hudong.com/wiki/%E7%B1%BB" target="_new" style="color: #0268cd; text-decoration: none; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">类</a><span style="color: #333333; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">文件的提供者（一个HTTP或者FTP服务器）&nbsp;</span><br style="color: #333333; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; " /><span style="color: #333333; font-family: Arial, 宋体, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#183;一个需要这个远程服务的客户端程序</span>&nbsp;<br />&nbsp; &nbsp;&nbsp;<br />&nbsp; &nbsp;&nbsp;来看下基于RMI的一次完整的远程通信过程的原理：<div>&nbsp;&nbsp;&nbsp;&nbsp;1)客户端发起请求，请求转交至RMI客户端的stub类；</div><div>&nbsp;&nbsp;&nbsp;&nbsp;2)stub类将请求的接口、方法、参数等信息进行序列化；</div><div>&nbsp;&nbsp;&nbsp;&nbsp;3)基于tcp/ip将序列化后的流传输至服务器端；</div><div>&nbsp;&nbsp;&nbsp;&nbsp;4)服务器端接收到流后转发至相应的skelton类；</div><div>&nbsp;&nbsp;&nbsp;&nbsp;5)skelton类将请求的信息反序列化后调用实际的处理类；</div><div>&nbsp;&nbsp;&nbsp;&nbsp;6)处理类处理完毕后将结果返回给skelton类；</div><div>&nbsp;&nbsp;&nbsp;&nbsp;7)Skelton类将结果序列化，通过tcp/ip将流传送给客户端的stub；</div><div>&nbsp;&nbsp;&nbsp;&nbsp;8)stub在接收到流后反序列化，将反序列化后的Java Object返回给调用者。<br /><br />&nbsp; &nbsp; &nbsp;RMI应用级协议内容：</div></div><blockquote style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; border-image: initial; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><div><div><div>1、传输的标准格式是什么？</div></div></div><div><div><div>&nbsp; &nbsp; &nbsp; 是Java ObjectStream。</div></div></div><div><div><div>2、怎么样将请求转化为传输的流？</div></div></div><div><div><div>&nbsp; &nbsp; &nbsp; 基于Java串行化机制将请求的java object信息转化为流。</div></div></div><div><div><div>3、怎么接收和处理流？</div></div></div><div><div><div>&nbsp; &nbsp; &nbsp; 根据采用的协议启动相应的监听端口，当有流进入后基于Java串行化机制将流进行反序列化，并根据RMI协议获取到相应的处理对象信息，进行调用并处理，处理完毕后的结果同样基于java串行化机制进行返回。</div></div></div><div><div><div>4、传输协议是？</div></div></div><div>&nbsp; &nbsp; &nbsp; tcp/ip。<br /><br /><strong>原理讲了，开始实践：</strong></div><span style="color: #000000; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">创建RMI程序的6个步骤：&nbsp;</span><br style="color: #000000; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; " /><span style="color: #000000; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">1、定义一个远程接口的接口，该接口中的每一个方法必须声明它将产生一个RemoteException异常。&nbsp;</span><br style="color: #000000; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; " /><span style="color: #000000; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">2、定义一个实现该接口的类。&nbsp;</span><br style="color: #000000; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; " /><span style="color: #000000; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">3、使用RMIC程序生成远程实现所需的残根和框架。&nbsp;</span><br style="color: #000000; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; " /><span style="color: #000000; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">4、创建一个服务器，用于发布2中写好的类。&nbsp;</span><br style="color: #000000; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; " /><span style="color: #000000; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">5. 创建一个客户程序进行RMI调用。&nbsp;</span><br style="color: #000000; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; " /><span style="color: #000000; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; text-align: left; background-color: #ffffff; ">6、启动rmiRegistry并运行自己的远程服务器和客户程序&nbsp;</span>&nbsp; &nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;<br />1）首先创建远程接口：<br /> &nbsp;<span style="color: #008000; background-color: #eeeeee; font-size: 13px; ">/**</span></blockquote><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><font color="#008000">&nbsp;*&nbsp;远程接口</font><br /><font color="#008000">&nbsp;*&nbsp;</font><br /><font color="#008000">&nbsp;*&nbsp;</font><span style="color: #808080; ">@author</span><span style="color: #008000; ">&nbsp;mike<br />&nbsp;*<br />&nbsp;*&nbsp;</span><span style="color: #808080; ">@since</span><span style="color: #008000; ">&nbsp;2012-3-14<br />&nbsp;</span><span style="color: #008000; ">*/</span><br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">interface</span>&nbsp;Hello&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;Remote&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;测试rmi&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080; ">@return</span><span style="color: #008000; ">&nbsp;&nbsp;&nbsp;hello<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080; ">@throws</span><span style="color: #008000; ">&nbsp;RemoteException<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;String&nbsp;hello()<span style="color: #0000FF; ">throws</span>&nbsp;RemoteException;<br />}</div><div>&nbsp; &nbsp; &nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; 2）创建接口实现<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="background-color: #eeeeee; font-size: 13px; color: #0000ff; ">package</span><span style="background-color: #eeeeee; font-size: 13px; ">&nbsp;com.gewara.rmi;</span><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><br /><span style="color: #0000FF; ">import</span>&nbsp;java.rmi.RemoteException;<br /><span style="color: #0000FF; ">import</span>&nbsp;java.rmi.server.UnicastRemoteObject;<br /><br /><span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;*&nbsp;远程接口实现<br />&nbsp;*&nbsp;<br />&nbsp;*&nbsp;</span><span style="color: #808080; ">@author</span><span style="color: #008000; ">&nbsp;mike<br />&nbsp;*<br />&nbsp;*&nbsp;</span><span style="color: #808080; ">@since</span><span style="color: #008000; ">&nbsp;2012-3-14<br />&nbsp;</span><span style="color: #008000; ">*/</span><br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;HelloImpl&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;UnicastRemoteObject&nbsp;<span style="color: #0000FF; ">implements</span>&nbsp;Hello&nbsp;{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;seria&nbsp;id<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;<span style="color: #0000FF; ">long</span>&nbsp;serialVersionUID&nbsp;=&nbsp;-7931720891757437009L;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">protected</span>&nbsp;HelloImpl()&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;RemoteException&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">super</span>();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;hello实现<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080; ">@return</span><span style="color: #008000; ">&nbsp;hello&nbsp;world<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080; ">@throws</span><span style="color: #008000; ">&nbsp;RemoteException<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;String&nbsp;hello()&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;RemoteException&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;"hello&nbsp;world";<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />}</div><br />&nbsp; &nbsp; &nbsp; &nbsp;3)创建服务器端<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="background-color: #eeeeee; font-size: 13px; color: #0000ff; ">package</span><span style="background-color: #eeeeee; font-size: 13px; ">&nbsp;com.gewara.rmi;</span><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><br /><span style="color: #0000FF; ">import</span>&nbsp;java.rmi.Naming;<br /><span style="color: #0000FF; ">import</span>&nbsp;java.rmi.registry.LocateRegistry;<br /><br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;Server&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;String&nbsp;RMI_URL="rmi://192.168.2.89:10009/server";<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;RMI&nbsp;Server<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;Server()&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">try</span>&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">创建远程对象</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hello&nbsp;hello=<span style="color: #0000FF; ">new</span>&nbsp;HelloImpl();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">启动注册表</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LocateRegistry.createRegistry(10009);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">将名称绑定到对象</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Naming.bind(RMI_URL,&nbsp;hello);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">catch</span>&nbsp;(Exception&nbsp;e)&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080; ">@param</span><span style="color: #008000; ">&nbsp;args<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(String[]&nbsp;args)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Server();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />}</div><br />&nbsp; &nbsp; &nbsp; &nbsp; 4)创建客服端<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="background-color: #eeeeee; font-size: 13px; color: #0000ff; ">package</span><span style="background-color: #eeeeee; font-size: 13px; ">&nbsp;com.gewara.rmi;</span><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><br /><span style="color: #0000FF; ">import</span>&nbsp;java.rmi.Naming;<br /><br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;Client&nbsp;{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;String&nbsp;RMI_URL="rmi://192.168.2.89:10009/server";<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080; ">@param</span><span style="color: #008000; ">&nbsp;args<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(String[]&nbsp;args)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">try</span>&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;result=((Hello)Naming.lookup(RMI_URL)).hello();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(result);&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">catch</span>&nbsp;(Exception&nbsp;e)&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />}</div><br />&nbsp; &nbsp; 5)先启动服务器端，然后再启动客户端<br />&nbsp; &nbsp; &nbsp; &nbsp;显示结果：hello world<br /><br />由于涉及到的内容比较多，打算每一篇里讲一个远程通讯框架，继续详解RMI<br />&nbsp;&nbsp;&nbsp;&nbsp;<br /><strong>三：详解RMI内部原理<br /></strong>1. RMI基本结构：包含两个独立的程序，服务器和客户端，服务器创建多个远程对象，让远程对象能够被引用，等待客户端调用这些远程对象的方法。客户端从服务器获取到一个或则多个远程对象的引用，然后调用远程对象方法，主要涉及到RMI接口、回调等技术。<br /><br />2.RMI回调：服务器提供远程对象引用供客户端调用，客户端主动调用服务器，如果服务器主动打算调用客户端，这就叫回调。<br /><br />3.命名远程对象：客户端通过一个命名或则一个查找服务找到远程服务，远程服务包含Java的命名和查找接口(Java Naming and Directory Interface)JNDI<br />RMI提供了一种服务:RMI注册rmiregistry,默认端口：1099，主机提供远程服务，接受服务，启动注册服务的命令：start rmiregistry<br />客户端使用一个静态类Naming到达RMI注册处，通过方法lookup()方法，客户来询问注册。</div><div></div><img src ="http://www.blogjava.net/mikechen/aggbug/371703.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mikechen/" target="_blank">陈睿</a> 2012-03-12 09:57 <a href="http://www.blogjava.net/mikechen/archive/2012/03/12/371703.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>