fhttpclient nio用的是nio还是io

NIO框架之MINA源码解析(五):NIO超级陷阱和使用同步IO与MINA通信 - 推酷
NIO框架之MINA源码解析(五):NIO超级陷阱和使用同步IO与MINA通信
1、NIO超级陷阱
之所以说NIO超级陷阱,就是因为我在本系列开头的那句话,因为使用缺陷导致客户业务系统瘫痪。当然,我对这个问题进行了很深的追踪,包括对MINA源码的深入了解,但其实之所以会出现这个问题,它的根不是MINA的原因,而是JDK底层的问题。
JDK底层在实现nio时,为了能够唤醒等待在io上的线程,在windows平台使用了两个端口建立连接发消息实现。看如下代码:
public class NIOTest {
public void test1(){
final int MAXSIZE=1000;
Selector [] sels = new Selector[ MAXSIZE];
for( int i = 0 ;i& MAXSIZE ;++i ) {
sels[i] = Selector.open();
Thread.sleep(1000*10);
}catch( Exception ex ){
ex.printStackTrace();
也就是说 每调用一次Selector.open(),就会占用两个随机可用端口 ,相互通信-- 这就是问题的根源 。
当然对于我们的项目来说,这个问题的解决需要分两步,首先限制端口数到用户可接受范围内,这个比较容易,我们可用只调用一次Selector.open()方法即可,使用单利模式;第二步,因为Selector.open()方法每次都是使用的系统当前可用的随机端口,所以就有可能导致占用客户业务端口的情况,因此我们必须把Selector.open()所开的端口限制在一定范围内,最好可以通过代码指定使用哪几个端口,但是直到现在我们都没有找到,如果亲们有方法的话,很感谢能够告诉我....,。
Selector总结如下: Windows下,Selector.open()会自己和自己建立两条TCP链接。不但消耗了两个TCP连接和端口,同时也消耗了文件描述符。 Linux下,Selector.open()会自己和自己建两条管道。同样消耗了两个系统的文件描述符。 来源于:http://blog.csdn.net/haoel/article/details/2224055 所以,现在我们现在就干脆用传统IO与MINA server通信吧。
2、使用同步IO与MINA通信
其实非常简单,唯一的难点就在于使用同步IO与MINA通信时,怎么编码和解码,还是看下面代码吧。
server 端(用的MINA)
* 初始化设置,启动服务
public void startServer() {
logger.debug(&mina server start&);
int port = SysEvnVar.managerP
logger.debug(&manager端口号:& + port);
IoAcceptor acceptor = new NioSocketAcceptor();
/** 日志设置 */
acceptor.getFilterChain().addLast(&logger&, new LoggingFilter());
//编码与解码工厂,使用的技术就是JDK提供的ObjectOutStream
ObjectSerializationCodecFactory objsCodec=new ObjectSerializationCodecFactory();
objsCodec.setDecoderMaxObjectSize(DEFAULTDECODER);
objsCodec.setEncoderMaxObjectSize(DEFAULTDECODER);
/** 数据转换,编码设置 */
acceptor.getFilterChain().addLast(
new ProtocolCodecFilter(objsCodec));
/** 设置业务处理类 */
acceptor.setHandler(serverHandler);
/** 设置buffer容量 */
acceptor.getSessionConfig().setReadBufferSize(DEFAULTBUFFERSIZE);
/** 设置空闲时间 */
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, DEFAULTIDLETIME);
/** 绑定端口 */
acceptor.bind(new InetSocketAddress(port));
(&mina server bind port (&+port+&) sucess&);
} catch (IOException e) {
logger.error(&mina server bind port (&+port+&) fail:& + e.getMessage(),e);
client端(使用同步IO)
public void sendMessageToManager(HyRequest request) {
Socket socket =
BufferedInputStream inBuff =
OutputStream outBuff =
Integer port = Integer.parseInt(hyGlobalConfigureCacheImpl.get(
&managerPort&).toString());
String host = hyGlobalConfigureCacheImpl.get(&managerIp&)
.toString();
socket = new Socket(host, port);
inBuff = new BufferedInputStream(new DataInputStream(
socket.getInputStream()));
outBuff = socket.getOutputStream();
String json = HyJsonUtil.reqeustToJsonStr(request);
//编码开始,使MINA能够解析
IoBuffer buf = IoBuffer.allocate(64);
buf.setAutoExpand(true);
buf.putObject(json);
buf.flip();
byte[] bytes =new byte[buf.limit()];
buf.get(bytes);
//编码结束,直接输出到客户端
outBuff.write(bytes);
outBuff.flush();
if(request.getOperation() != null && !&quit&.equals(request.getOperation())){
String allreadstr = new String();
byte[] b = new byte[512 * 1024];
byte[] tmp = new byte[0];
if ((len = inBuff.read(b)) != -1) {
tmp = new byte[len];
System.arraycopy(b, 0, tmp, 0, len);
loger.debug(&len:&+len);
//解码开始,byte[]为MINA传过来的数据
IoBuffer in = IoBuffer.wrap(tmp);
Object obj =
loger.debug(&in:&+in);
obj = in.getObject();
//解码结束
loger.debug(&parse success&);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
loger.debug(&go to exception&);
loger.warn(&nio parse exception&,e);
obj = &exception&;
allreadstr = (String)
(&receive message from &
+ socket.getRemoteSocketAddress().toString() + &,message:&
+ allreadstr);
// 请求消息转换为HyResponse对象
HyResponse response = HyJsonUtil.getHyResponse(allreadstr);
HyRequest hyrequest = new HyRequest();
hyResponseDispatcher = hyClientHandler.getHyResponseDispatcher();
hyResponseDispatcher.responseProcess(hyrequest, response);
if (hyrequest.getOperation() != null) {
sendMessageToManager2(hyrequest);
} catch (Exception e) {
e.printStackTrace();
} finally {
if(null != outBuff)
outBuff.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
if(null != inBuff)
inBuff.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
if (socket != null) {
socket.close();
} catch (IOException e) {
看代码里面的注释,怎么编码和解码,其实我是直接看MINA源码,把MINA的编码和解码方法工具类直接拷到了我们的client端,这样就轻松的实现使用同步IO和MINA进行通信。
已发表评论数()
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
排版有问题
没有分页内容
视频无法显示
图片无法显示502 Bad Gateway
Error 502源站异常(请求处理超时或者主动断开到牛盾加速节点的连接)如果您是网站管理员,点击查看
您的访问正常牛盾节点正常服务器访问错误

我要回帖

更多关于 nio和io的区别 的文章

 

随机推荐