我现在也在研究mina框架。。用的是2.0 的那个最新版本。。官方网站说那个版本还不稳定 。呵呵, 不过我还是用了。现在遇到了一个问题。我用mina做一个服务器端,然后用基本的socket去创建客户端,虽然可以连接到server,但是消息却传输不过来。也就是当我用一个用socket写的客户端去练剑mian server的时候,在server的handler类中只能走到sessionopend这个函数,却走不到messageRecieved这个函数,我想请教一下楼主,你对这方面有研究吗??我在官方网站上看到apache已经用mina开发了一个ftp服务器,我想这个服务器应该不会限制客户端用什么技术来跟它通讯,如果是那样的话,这个ftp服务器就做的太失败了,扩展性不好,不太适用?您认为呢??如果你知道怎么解决我说的问题的话,请到楼下接着写,我会经常来光顾这个帖子的, 谢谢你!!对了,我用mina的时候没用任何的filter,数据都是用iobuffer包装的。。

解决方案 »

  1.   

    建议你用filter,这是mina架构的优势之一,把编解码和具体的业务逻辑剥离开来,清晰,它的流程是这样的,当和server建立连接后,Client--》handler-->filter-->(server端)--》filter--》handler,你可以一部部调试,先要保证msg发送出去,可以在client 的handler 里messagesent(){}方法里监控是否已经发送成功,然后在messagereceived(){}里看有没有接收到
      

  2.   

        谢谢楼主的回复!!
    我尝试着用了filter,可是我要传输的数据里面有文件和字符串,我不知道用哪个过滤器可以实现这种编码??您知道吗??因为不知道用哪个filter,所以一直都没用,直接用的最底层的数据封装iobuffer。封装起来还是挺简单的, 没有那么复杂。我想要知道的是用mina构造一个服务器端,然后客户端不用mina里面的任何包,是否也可以把数据传输,因为所开发的项目可能会在j2me上跑,如果运用mina的话,似乎无法在j2me上运行。。我自己写了一个socket客户端,与mina服务器端进行了通讯,然而却无法把数据发送到服务器端。。当我将数据从客户端发送的时候,能够与mina server 建立连接,因为mina框架是一个事件驱动模型的,所以在当客户端发送数据的时候触发了minaserver handler的sessionOpened(IoSession)函数,但是无法触发messagereceived函数??我就是想知道,可以不用mina做客户端吗?如果可以的话,编码问题又应该怎么解决?mina最底层的数据封装就是iobuffer,可是这个类还是在Mina的jar包里面,难道说这是mina的弊端,只能同时运用mina框架才能保证客户端和服务器端的正常通讯?不过这似乎又有点说不过去,一个服务器怎么可能要求客户运用什么技术呢???
      

  3.   

    Mina的速度太慢,每一次通讯来回大概要200多毫秒 AIX上
    而采用nio.Selector 只需要5毫秒多一点 
      

  4.   

    那你可以自己用java的NIO包实现通讯底层
      

  5.   

    我测试了一下,发500字节的msg,时间上只需要几十毫秒左右
      

  6.   

     Group home page: http://groups.google.com/group/mina4apache 
    进去就知道了,如果稍微懂点英语的话
      

  7.   

    楼主请教您一个问题。在运用Mina框架的时候你是否注意到,在server和client通讯的时候是否没有释放对象,而导致内存溢出呢?
    如代码:
    SocketConnector connector = new NioSocketConnector(); // 创建SocketAddress对象
    SocketAddress address = new InetSocketAddress(
    SheetServer.bankServerName,SheetServer.bankServerPort);
    connector.setDefaultRemoteAddress(address);
    connector.setHandler(new SheetClientHandler(status));
    // 建立连接
     connector.connect();
    如果你做个测试,启用多个客户端,你会发现线程数一直在增加,而且等通讯结束后线程数还是没有减少,不知道您有没有解决这个问题的方法,也就是单例模式,是否可以在每次创建连接的时候判断是否已经存在connnector对象,如果存在就不再创建该对象??
      

  8.   

    mina框架是否不适合做客户端?我想apache公司在开发这个框架的时候一定考虑过内存问题,不可能不能释放的,希望楼主能给点见解!!
      

  9.   

    经过LoadRunner8.0测试,1000个client发送数据给server端,抛出JVM的内存错误,后加大JVM运行时内存,问题解决。
    测试机IBM T61 T7100 1.8GHz,2GB,Vista SP1.========================客户端=================================
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.charset.Charset;
    import org.apache.mina.common.ConnectFuture;
    import org.apache.mina.common.IoBuffer;
    import org.apache.mina.common.IoConnector;
    import org.apache.mina.common.IoFutureListener;
    import org.apache.mina.common.IoHandlerAdapter;
    import org.apache.mina.common.IoSession;
    import org.apache.mina.transport.socket.nio.NioSocketConnector;import com.nantian.mina.server.ServerHandler;public class ClientHandler extends IoHandlerAdapter{
        
    private static final String remoteAdd = "localhost";

    private IoSession session;

    private IoConnector connection;

    public ClientHandler(){
           connection  =  new NioSocketConnector();
           connection.setHandler(this);
           ConnectFuture connFuture = connection.connect(new InetSocketAddress(remoteAdd,ServerHandler.PORT));
           connFuture.addListener(new IoFutureListener<ConnectFuture>() {
                public void operationComplete(ConnectFuture future) {
                    if (future.isConnected()) {
                        session = future.getSession();
                        try {
                            sendData();
                            Thread.sleep(2000);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    } else {
                       System.out.println("连接不存在");
                    }
                }
            });
    }

    public void sendData(){
    try {
    StringBuffer sf = new StringBuffer();
    sf.append("客户端数据");
    IoBuffer buffer = IoBuffer.allocate(20480,true);//分清楚direct和heap方式的缓冲区别
    buffer.setAutoExpand(true);//自动扩张
    buffer.setAutoShrink(true);//自动收缩
    buffer.putString(sf.toString(), Charset.forName("gb2312").newEncoder());
    buffer.flip();
    buffer.free();
    session.write(buffer);

    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }



    @Override
    public void exceptionCaught(IoSession session, Throwable cause)
    throws Exception {
    super.exceptionCaught(session, cause);
    } @Override
    public void messageReceived(IoSession session, Object message)
    throws Exception {
    super.messageReceived(session, message);
    }

    public static void main(String[] args) {
    new ClientHandler();
    }========================服务端=================================
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.charset.Charset;
    import java.util.concurrent.Executor;
    import java.util.concurrent.Executors;import org.apache.mina.common.IoBuffer;
    import org.apache.mina.common.IoHandlerAdapter;
    import org.apache.mina.common.IoSession;
    import org.apache.mina.filter.executor.ExecutorFilter;
    import org.apache.mina.transport.socket.nio.NioDatagramAcceptor;
    import org.apache.mina.transport.socket.nio.NioSocketAcceptor;import com.nantian.mina.control.Control;
    import com.nantian.mina.test.MyFilter;public class ServerHandler extends IoHandlerAdapter{
        
    public static final int PORT = 12345;

    private NioSocketAcceptor tcpAcceptor;

    private NioDatagramAcceptor udpAcceptor;

    public ServerHandler(){
    Executor threadPool = Executors.newFixedThreadPool(1500);//建立线程池
    tcpAcceptor = new NioSocketAcceptor();
    tcpAcceptor.getFilterChain().addLast("exector", new ExecutorFilter(threadPool));
    tcpAcceptor.getFilterChain().addLast("myFilter",new MyFilter());
        tcpAcceptor.setHandler(this);
    //     udpAcceptor = new NioDatagramAcceptor();
    //     udpAcceptor.getFilterChain().addLast("exector", new ExecutorFilter(threadPool));
    //     udpAcceptor.setHandler(this);
        try {
         tcpAcceptor.setBacklog(200);//设置主服务监听端口的监听队列的最大值为100,如果当前已经有100个连接,再新的连接来将被服务器拒绝
         tcpAcceptor.setReuseAddress(true);//设置的是主服务监听的端口可以重用
         //udpAcceptor.getSessionConfig().setReuseAddress(true);//设置每一个非主监听连接的端口可以重用
         tcpAcceptor.getSessionConfig().setTcpNoDelay(true);//设置为非延迟发送,为true则不组装成大包发送,收到东西马上发出
         tcpAcceptor.getSessionConfig().setReceiveBufferSize(10240);//设置输入缓冲区的大小
         tcpAcceptor.getSessionConfig().setSendBufferSize(10240);//设置输出缓冲区的大小
         tcpAcceptor.setDefaultLocalAddress(new InetSocketAddress(PORT)); 
         tcpAcceptor.bind();
    System.out.println("启动程序");
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }   
    }
     
    @Override
    public void exceptionCaught(IoSession session, Throwable cause)
    throws Exception {
    System.out.println(cause);
    session.close();
    } @Override
    public void messageReceived(IoSession session, Object message)
    throws Exception {
    IoBuffer buffer = (IoBuffer)message;
    String recvMsg = buffer.getString(Charset.forName("gb2312").newDecoder());
    buffer.free();
    Control.DATANUM++;
    System.out.println("收到消息"+recvMsg);
    System.out.println(tcpAcceptor.getManagedSessionCount());
    }

    public static void main(String[] args) {
    new ServerHandler();
    }说明:代码用于测试,所以有点杂乱,望谅解。MINA版本2.0,现在贴出来我的代码是希望初学者学习,当然也非常希望高手帮助优化一下,给点意见。我的联系方式:[email protected]谢谢!
      

  10.   

    Kmlrz    tcpAcceptor.setBacklog(200);//设置主服务监听端口的监听队列的最大值为100,如果当前已经有100个连接,再新的连接来将被服务器拒绝 你这样做虽然说可以减轻服务器的负担,但是实际上我们开发项目的时候有可能100个连接并不能满足客户的需要。比如说给银行做一个信用卡支付管理系统。全国支持刷卡的地方不只100家吧?那么在传输数据的时候如果你只允许建立100个连接,还有很多家的家里数据是不能在同一时间上传的。只能等待有空余的连接才能够上传交易数据。有没有更好的方法。比如说代码的优化,或者说mina里面已经存在一个函数可以在客户端与服务器端交易结束后可以释放这个对象?
      

  11.   

     我用mina做项目 遇到了内存泄漏   我确定发生的地方是在服务器端的输出有泄漏..
     
     
            我用客户端不停的发送包到服务器端,   服务器端接收到后  发一个包返回到客户端.
     
               可就是在这样  会看见服务器的内存一直上升..  我观察了  是客户端  接收到的包很少.
     
     
                     我认为是服务器端的包没有发送出去导致的..  
     
                              但是我把客户端关闭了   服务器端得内存仍然不释放呀 ..   你说是什么原因 我对mina的机制还不是很熟悉    
     
     
    谢谢你呀
      

  12.   

    我最近给我们项目的系统做性能测试,我们的系统是Server端,使用mina。但是测试中发现,当TCP连接数达到不到200时就会出现连不上Server的情况,需要重连几次后才可以。一直没查到原因,一般出现这种情况会是什么原因呢,以mina的性能,应该不止只支持这么点的连接吧?服务器端:
    IoAcceptor acceptor = null;
                // 创建一个非阻塞的server端的Socket
                acceptor = new NioSocketAcceptor(); addFilter(acceptor);
    // 绑定逻辑处理器
    acceptor.setHandler(rtspListener); // 绑定端口
    acceptor.bind(new InetSocketAddress(PORT));
    其中的addFilter为:private void addFilter(IoAcceptor acceptor) { // 设置过滤器(添加编解码器)
    acceptor.getFilterChain().addLast("codec",
    new ProtocolCodecFilter(new RtspProtocolCodecFactory()));
    //FIXME 测试
    Executor threadPool = Executors.newFixedThreadPool(Runtime.getRuntime()
                    .availableProcessors() + 1); acceptor.getFilterChain().addLast("exector",
    new ExecutorFilter(threadPool));
    }
      

  13.   

    //udpAcceptor.getSessionConfig().setReuseAddress(true);//设置每一个非主监听连接的端口可以重用这个是作用是什么?是否mina重启的时候,如果这个时候还有端口被客户端占用,会重用?有没有人遇到过,服务器启动了mina,然后关闭,再重启的时候,就会出现端口占用的情况
    看到端口,发现有客户端在连接的(mina在等待客户端回应,其实这时客户端早就断开了。上一次mina服务器就已经关闭了)
    最后搞得只能物理重启了