javamina,javamina数据读取不全

本文目录一览:

java mina 数据发送前怎样判断连接状态

1 Mina基本开发知识

1.1 非阻塞模式

Java NIO非堵塞应用通常适用用在I/O读写等方面,我们知道,系统运行的性能瓶颈通常在I/O读写,包括对端口和文件的操作上,过去,在打开一个I/O通道后,read()将一直等待在端口一边读取字节内容,如果没有内容进来,read()也是傻傻的等,这会影响我们程序继续做其他事情,那么改进做法就是开设线程,让线程去等待,但是这样做也是相当耗费资源(传统socket通讯服务器设计模式)的。

Java NIO非堵塞技术实际是采取Reactor模式,或者说是Observer模式为我们监察I/O端口,如果有内容进来,会自动通知我们,这样,我们就不必开启多个线程死等,从外界看,实现了流畅的I/O读写,不堵塞了。

Java NIO出现不只是一个技术性能的提高,你会发现网络上到处在介绍它,因为它具有里程碑意义,从JDK1.4开始,Java开始提高性能相关的功能,从而使得Java在底层或者并行分布式计算等操作上已经可以和C或Perl等语言并驾齐驱。

如果你至今还是在怀疑Java的性能,说明你的思想和观念已经完全落伍了,Java一两年就应该用新的名词来定义。从JDK1.5开始又要提供关于线程、并发等新性能的支持,Java应用在游戏等适时领域方面的机会已经成熟,Java在稳定自己中间件地位后,开始蚕食传统C的领域。

NIO 有一个主要的类Selector,这个类似一个观察者,只要我们把需要探知的socketchannel告诉Selector,我们接着做别的事情,当有事件发生时,他会通知我们,传回一组SelectionKey,我们读取这些Key,就会获得我们刚刚注册过的socketchannel,然后,我们从这个Channel中读取数据,放心,包准能够读到,接着我们可以处理这些数据。Selector内部原理实际是在做一个对所注册的channel的轮询访问,不断的轮询(目前就这一个算法),一旦轮询到一个channel有所注册的事情发生,比如数据来了,他就会站起来报告,交出一把钥匙,让我们通过这把钥匙(SelectionKey表示 SelectableChannel 在 Selector 中的注册的标记。 )来读取这个channel的内容.

1.2 什么是mian

现在已经是World Wide Web的时代,无数的web应用框架被创造出来从而大大的提高了web开发的速度。抛开WWW的这个优势,我们知道还有很多协议是HTTP协议所无法替代的。有时,我们仍然需要构造c/s应用来实现适当的协议。

你有没有曾经使用java或者其他语言实现过某个协议栈?就像你所经历过的那样,编写网络应用即使对于有经验的开发者也不是容易的事情。这归咎于以下几个方面:

* 没有为开发者设计的合适的网络应用框架.

* 使你无法在有限的时间内创建你的应用.

* 网络I/O编码,消息的编/解码,业务逻辑常常纠缠在一起.

* 使程序失去可维护性和可复用性

* 网络应用难于进行单元测试

* 你失去了敏捷性

MINA是一个网络应用框架,在不牺牲性能和可扩展性的前提下用于解决上面的所有问题。

1.3 几个接口

IoAcceptor执行所有底层IO,将他们翻译成抽象的IO事件,并把翻译

java mina 可以多线程写么

MINA,Grizzly[grizzly-nio-framework],xSocket都是基于javanio的serverframework.这里的性能缺陷的焦点是指当一条channel上的SelectionKey.OP_READready时,1.是由selectthread读完数据之后再分发给应用程序的handler,2.还是直接就分发,由handlerthread来负责读数据和handle.mina,xsocket是1.grizzly-nio-framework是2.尽管读channelbuffer中bytes是很快的,但是如果我们放大,当连接channel达到上万数量级,甚至,这种延迟响应的效果将会愈加明显.MINA:forallselectedKeys{readdatathenfireMessageReceived.}xSocket:forallselectedKeys{readdata,appendittoreadQueuethenperformOnData.}其中mina在fireMessageReceived时没有使用threadpool来分发,所以需要应用程序在handler.messageReceived中再分发.而xsocket的performOnData默认是分发给threadpool[WorkerPool],WorkerPool虽然解决了线程池中的线程不能充到最大的问题[跟tomcat6的做法一样],但是它的调度机制依然缺乏灵活性.Grizzly:forallselectedKeys{[NIOContext—filterChain.execute—ourfilter.execute]bindInternal—startupAcceptor:启动AbstractPollingIoAcceptor.Acceptor.run使用executor[Executor]的线程,注册[interestOps:SelectionKey.OP_ACCEPT],然后wakeupselector.一旦有连接进来就构建NioSocketSession–对应–channal,然后session.getProcessor().add(session)将当前的channal加入到NioProcessor的selector中去[interestOps:SelectionKey.OP_READ],这样每个连接中有请求过来就由相应的NioProcessor来处理.这里有几点要说明的是:1.一个NioSocketAcceptor对应了多个NioProcessor,比如NioSocketAcceptor就使用了SimpleIoProcessorPoolDEFAULT_SIZE=Runtime.getRuntime().availableProcessors()+1.当然这个size在newNioSocketAcceptor的时候可以设定.2.一个NioSocketAcceptor对应一个javanioselector[OP_ACCEPT],一个NioProcessor也对应一个javanioselector[OP_READ].3.一个NioSocketAcceptor对应一个内部的AbstractPollingIoAcceptor.Acceptor—thread.4.一个NioProcessor也对应一个内部的AbstractPollingIoProcessor.Processor—thread.5.在newNioSocketAcceptor的时候如果你不提供Executor(线程池)的话,那么默认使用Executors.newCachedThreadPool().这个Executor将被NioSocketAcceptor和NioProcessor公用,也就是说上面的Acceptor—thread(一条)和Processor—thread(多条)都是源于这个Executor.当一个连接javaniochannal–NioSession被加到ProcessorPool[i]–NioProcessor中去后就转入了AbstractPollingIoProcessor.Processor.run,AbstractPollingIoProcessor.Processor.run方法是运行在上面的Executor中的一条线程中的,当前的NioProcessor将处理注册在它的selector上的所有连接的请求[interestOps:SelectionKey.OP_READ].AbstractPollingIoProcessor.Processor.run的主要执行流程:for(;;){intselected=selector(finalSELECT_TIMEOUT=1000L);.if(selected0){process();}}process()–forallsession-channal:OP_READ–read(session):这个read方法是AbstractPollingIoProcessor.privatevoidread(Tsession)方法.read(session)的主要执行流程是readchannal-datatobuf,ifreadBytes0thenIoFilterChain.fireMessageReceived(buf)/*我们的IoHandler.messageReceived将在其中被调用*/;到此minaNio处理请求的流程已经明了.mina处理请求的线程模型也出来了,性能问题也来了,那就是在AbstractPollingIoProcessor.Processor.run–process–read(persession)中,在process的时候mina是forallselected-channals逐次readdata再fireMessageReceived到我们的IoHandler.messageReceived中,而不是并发处理,这样一来很明显后来的请求将被延迟处理.我们假设:如果NioProcessorPool’ssize=2现在有200个客户端同时连接过来,假设每个NioProcessor都注册了100个连接,对于每个NioProcessor将依次顺序处理这100个请求,那么这其中的第100个请求要得到处理,那它只有等到前面的99个被处理完了.有人提出了改进方案,那就是在我们自己的IoHandler.messageReceived中利用线程池再进行分发dispatching,这个当然是个好主意.但是请求还是被延迟处理了,因为还有readdata所消耗的时间,这样第100个请求它的数据要被读,就要等前面的99个都被读完才行,即便是增加ProcessorPool的尺寸也不能解决这个问题.此外mina的陷阱(这个词较时髦)也出来了,就是在read(session)中,在说这个陷阱之前先说明一下,我们的client端向server端发送一个消息体的时候不一定是完整的只发送一次,可能分多次发送,特别是在client端忙或要发送的消息体的长度较长的时候.而mina在这种情况下就会call我们的IoHandler.messageReceived多次,结果就是消息体被分割了若干份,等于我们在IoHandler.messageReceived中每次处理的数据都是不完整的,这会导致数据丢失,无效.下面是read(session)的源码:privatevoidread(Tsession){IoSessionConfigconfig=session.getConfig();IoBufferbuf=IoBuffer.allocate(config.getReadBufferSize());finalbooleanhasFragmentation=session.getTransportMetadata().hasFragmentation();try{intreadBytes=0;intret;try{if(hasFragmentation/*hasFragmentation一定为ture,也许mina的开发人员也意识到了传输数据的碎片问题,但是靠下面的处理是远远不够的,因为client一旦间隔发送,ret就可能为0,退出while,不完整的readBytes将被fire*/){while((ret=read(session,buf))0){readBytes+=ret;if(!buf.hasRemaining()){break;}}}else{ret=read(session,buf);if(ret0){readBytes=ret;}}}finally{buf.flip();}if(readBytes0){IoFilterChainfilterChain=session.getFilterChain();filterChain.fireMessageReceived(buf);buf=null;if(hasFragmentation){if(readBytesIoAcceptor.accept()在port上阻塞,一旦有channel就从IoSocketDispatcherPool中获取一个IoSocketDispatcher,同时构建一个IoSocketHandler和NonBlockingConnection,调用Server.LifeCycleHandler.onConnectionAccepted(ioHandler)initializetheIoSocketHandler.注意:IoSocketDispatcherPool.size默认为2,也就是说只有2条doselect的线程和相应的2个IoSocketDispatcher.这个和MINA的NioProcessor数是一样的.说明2.IoSocketDispatcher[javanioSelector]:IoSocketHandler:NonBlockingConnection——1:1:1在IoSocketDispatcher[对应一个Selector].run中—IoSocketDispatcher.handleReadWriteKeys:forallselectedKeys{IoSocketHandler.onReadableEvent/onWriteableEvent.}IoSocketHandler.onReadableEvent的处理过程如下:1.readSocket();2.NonBlockingConnection.IoHandlerCallback.onDataNonBlockingConnection.onData—appendDataToReadBuffer:readQueueappenddata3.NonBlockingConnection.IoHandlerCallback.onPostDataNonBlockingConnection.onPostData—HandlerAdapter.onData[ourdataHandler]performOnDatainWorkerPool[threadpool].因为是把channel中的数据读到readQueue中,应用程序的dataHandler.onData会被多次调用直到readQueue中的数据读完为止.所以依然存在类似mina的陷阱.解决的方法依然类似,因为这里有NonBlockingConnection.———————————————————————————————-再下面以grizzly-nio-frameworkv1.9.18源码为例:tcpusagee.g:Controllersel=newController();sel.setProtocolChainInstanceHandler(newDefaultProtocolChainInstanceHandler(){publicProtocolChainpoll(){ProtocolChainprotocolChain=protocolChains.poll();if(protocolChain==null){protocolChain=newDefaultProtocolChain();//protocolChain.addFilter(ourapp’sfilter/*应用程序的处理从filter开始,类似mina.ioHandler,xSocket.dataHandler*/);//protocolChain.addFilter(newReadFilter());}returnprotocolChain;}});//如果你不增加自己的SelectorHandler,Controller就默认使用TCPSelectorHandlerport:18888sel.addSelectorHandler(ourapp’sselectorHandleronspecialport);sel.start();————————————————————————————————————说明1.Controller:ProtocolChain:Filter——1:1:n,Controller:SelectorHandler——1:n,SelectorHandler[对应一个Selector]:SelectorHandlerRunner——1:1,Controller.start()—forperSelectorHandlerstartSelectorHandlerRunnertorun.SelectorHandlerRunner.run()—selectorHandler.select()thenhandleSelectedKeys:forallselectedKeys{NIOContext.execute:dispatchingtothreadpoolforProtocolChain.execute—ourfilter.execute.}你会发现这里没有readdatafromchannel的动作,因为这将由你的filter来完成.所以自然没有mina,xsocket它们的陷阱问题,分发提前了.但是你要注意SelectorHandler:Selector:SelectorHandlerRunner:Thread[SelectorHandlerRunner.run]都是1:1:1:1,也就是说只有一条线程在doSelectthenhandleSelectedKeys.相比之下虽然grizzly在并发性能上更优,但是在易用性方面却不如mina,xsocket,比如类似mina,xsocket中表示当前连接或会话的IoSession,INonBlockingConnection对象在grizzly中由NIOContext来负责,但是NIOContext并没有提供session/connectionlifecycleevent,以及常规的read/write操作,这些都需要你自己去扩展SelectorHandler和ProtocolFilter,从另一个方面也可以说明grizzly的可扩展性,灵活性更胜一筹.转载

java Mina服务器 java.io.IOException: Connection reset by peer,请问怎么解决?

这个错误其实是可以忽略的,影响不到运行,有时候客户端主动断开链接就会报这个错。你下面那个设置是线程池的设置跟这个没有关系的

java mina 怎么打成jar包放在服务器上呀~~

jar包在服务器上是不可运行的!

在服务器上运行的是WEB程序是war包

jar包的安装使用一般在手机上!

其次!jar包 是放在WEB程序下面的webroot下面的lib中的 只不过是给别人调用的!jar包 也可以做为插件 共别人使用!

因为要下班了!所以暂时这么说吧!不知道LZ能接受不。。。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/257053.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-15 12:43
下一篇 2024-12-15 12:43

相关推荐

  • Python读取CSV数据画散点图

    本文将从以下方面详细阐述Python读取CSV文件并画出散点图的方法: 一、CSV文件介绍 CSV(Comma-Separated Values)即逗号分隔值,是一种存储表格数据的…

    编程 2025-04-29
  • Python中读入csv文件数据的方法用法介绍

    csv是一种常见的数据格式,通常用于存储小型数据集。Python作为一种广泛流行的编程语言,内置了许多操作csv文件的库。本文将从多个方面详细介绍Python读入csv文件的方法。…

    编程 2025-04-29
  • 如何用Python统计列表中各数据的方差和标准差

    本文将从多个方面阐述如何使用Python统计列表中各数据的方差和标准差, 并给出详细的代码示例。 一、什么是方差和标准差 方差是衡量数据变异程度的统计指标,它是每个数据值和该数据值…

    编程 2025-04-29
  • Python多线程读取数据

    本文将详细介绍多线程读取数据在Python中的实现方法以及相关知识点。 一、线程和多线程 线程是操作系统调度的最小单位。单线程程序只有一个线程,按照程序从上到下的顺序逐行执行。而多…

    编程 2025-04-29
  • Python两张表数据匹配

    本篇文章将详细阐述如何使用Python将两张表格中的数据匹配。以下是具体的解决方法。 一、数据匹配的概念 在生活和工作中,我们常常需要对多组数据进行比对和匹配。在数据量较小的情况下…

    编程 2025-04-29
  • Python爬取公交数据

    本文将从以下几个方面详细阐述python爬取公交数据的方法: 一、准备工作 1、安装相关库 import requests from bs4 import BeautifulSou…

    编程 2025-04-29
  • Python数据标准差标准化

    本文将为大家详细讲述Python中的数据标准差标准化,以及涉及到的相关知识。 一、什么是数据标准差标准化 数据标准差标准化是数据处理中的一种方法,通过对数据进行标准差标准化可以将不…

    编程 2025-04-29
  • 如何使用Python读取CSV数据

    在数据分析、数据挖掘和机器学习等领域,CSV文件是一种非常常见的文件格式。Python作为一种广泛使用的编程语言,也提供了方便易用的CSV读取库。本文将介绍如何使用Python读取…

    编程 2025-04-29
  • Python如何打乱数据集

    本文将从多个方面详细阐述Python打乱数据集的方法。 一、shuffle函数原理 shuffle函数是Python中的一个内置函数,主要作用是将一个可迭代对象的元素随机排序。 在…

    编程 2025-04-29
  • Python根据表格数据生成折线图

    本文将介绍如何使用Python根据表格数据生成折线图。折线图是一种常见的数据可视化图表形式,可以用来展示数据的趋势和变化。Python是一种流行的编程语言,其强大的数据分析和可视化…

    编程 2025-04-29

发表回复

登录后才能评论